Skip to content

Commit 5f7f0b1

Browse files
TypeScript Botweswigham
TypeScript Bot
andauthored
Cherry-pick PR #49361 into release-4.7 (#49364)
Component commits: fce9115 Use node's algorithm for calculating the longest matching export/import pattern Co-authored-by: Wesley Wigham <[email protected]>
1 parent c07d883 commit 5f7f0b1

19 files changed

+2847
-1
lines changed

src/compiler/moduleNameResolver.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -2064,14 +2064,32 @@ namespace ts {
20642064
return toSearchResult(/*value*/ undefined);
20652065
}
20662066

2067+
/**
2068+
* From https://github.com/nodejs/node/blob/8f39f51cbbd3b2de14b9ee896e26421cc5b20121/lib/internal/modules/esm/resolve.js#L722 -
2069+
* "longest" has some nuance as to what "longest" means in the presence of pattern trailers
2070+
*/
2071+
function comparePatternKeys(a: string, b: string) {
2072+
const aPatternIndex = a.indexOf("*");
2073+
const bPatternIndex = b.indexOf("*");
2074+
const baseLenA = aPatternIndex === -1 ? a.length : aPatternIndex + 1;
2075+
const baseLenB = bPatternIndex === -1 ? b.length : bPatternIndex + 1;
2076+
if (baseLenA > baseLenB) return -1;
2077+
if (baseLenB > baseLenA) return 1;
2078+
if (aPatternIndex === -1) return 1;
2079+
if (bPatternIndex === -1) return -1;
2080+
if (a.length > b.length) return -1;
2081+
if (b.length > a.length) return 1;
2082+
return 0;
2083+
}
2084+
20672085
function loadModuleFromImportsOrExports(extensions: Extensions, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined, moduleName: string, lookupTable: object, scope: PackageJsonInfo, isImports: boolean): SearchResult<Resolved> | undefined {
20682086
const loadModuleFromTargetImportOrExport = getLoadModuleFromTargetImportOrExport(extensions, state, cache, redirectedReference, moduleName, scope, isImports);
20692087

20702088
if (!endsWith(moduleName, directorySeparator) && moduleName.indexOf("*") === -1 && hasProperty(lookupTable, moduleName)) {
20712089
const target = (lookupTable as {[idx: string]: unknown})[moduleName];
20722090
return loadModuleFromTargetImportOrExport(target, /*subpath*/ "", /*pattern*/ false);
20732091
}
2074-
const expandingKeys = sort(filter(getOwnKeys(lookupTable as MapLike<unknown>), k => k.indexOf("*") !== -1 || endsWith(k, "/")), (a, b) => a.length - b.length);
2092+
const expandingKeys = sort(filter(getOwnKeys(lookupTable as MapLike<unknown>), k => k.indexOf("*") !== -1 || endsWith(k, "/")), comparePatternKeys);
20752093
for (const potentialTarget of expandingKeys) {
20762094
if (state.features & NodeResolutionFeatures.ExportsPatternTrailers && matchesPatternWithTrailer(potentialTarget, moduleName)) {
20772095
const target = (lookupTable as {[idx: string]: unknown})[potentialTarget];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
tests/cases/conformance/node/allowJs/index.cjs(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
2+
tests/cases/conformance/node/allowJs/index.cjs(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
3+
tests/cases/conformance/node/allowJs/index.cjs(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
4+
tests/cases/conformance/node/allowJs/index.js(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
5+
tests/cases/conformance/node/allowJs/index.js(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
6+
tests/cases/conformance/node/allowJs/index.js(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
7+
tests/cases/conformance/node/allowJs/index.mjs(2,23): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
8+
tests/cases/conformance/node/allowJs/index.mjs(3,23): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
9+
tests/cases/conformance/node/allowJs/index.mjs(4,24): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
10+
tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
11+
tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
12+
tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
13+
tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
14+
tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
15+
tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
16+
tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts(2,22): error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
17+
tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts(3,22): error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
18+
tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts(4,23): error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
19+
20+
21+
==== tests/cases/conformance/node/allowJs/index.js (3 errors) ====
22+
// esm format file
23+
import * as cjsi from "inner/cjs/exclude/index";
24+
~~~~~~~~~~~~~~~~~~~~~~~~~
25+
!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
26+
import * as mjsi from "inner/mjs/exclude/index";
27+
~~~~~~~~~~~~~~~~~~~~~~~~~
28+
!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
29+
import * as typei from "inner/js/exclude/index";
30+
~~~~~~~~~~~~~~~~~~~~~~~~
31+
!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
32+
cjsi;
33+
mjsi;
34+
typei;
35+
==== tests/cases/conformance/node/allowJs/index.mjs (3 errors) ====
36+
// esm format file
37+
import * as cjsi from "inner/cjs/exclude/index";
38+
~~~~~~~~~~~~~~~~~~~~~~~~~
39+
!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
40+
import * as mjsi from "inner/mjs/exclude/index";
41+
~~~~~~~~~~~~~~~~~~~~~~~~~
42+
!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
43+
import * as typei from "inner/js/exclude/index";
44+
~~~~~~~~~~~~~~~~~~~~~~~~
45+
!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
46+
cjsi;
47+
mjsi;
48+
typei;
49+
==== tests/cases/conformance/node/allowJs/index.cjs (3 errors) ====
50+
// cjs format file
51+
import * as cjsi from "inner/cjs/exclude/index";
52+
~~~~~~~~~~~~~~~~~~~~~~~~~
53+
!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
54+
import * as mjsi from "inner/mjs/exclude/index";
55+
~~~~~~~~~~~~~~~~~~~~~~~~~
56+
!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
57+
import * as typei from "inner/js/exclude/index";
58+
~~~~~~~~~~~~~~~~~~~~~~~~
59+
!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
60+
cjsi;
61+
mjsi;
62+
typei;
63+
==== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.ts (3 errors) ====
64+
// cjs format file
65+
import * as cjs from "inner/cjs/exclude/index";
66+
~~~~~~~~~~~~~~~~~~~~~~~~~
67+
!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
68+
import * as mjs from "inner/mjs/exclude/index";
69+
~~~~~~~~~~~~~~~~~~~~~~~~~
70+
!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
71+
import * as type from "inner/js/exclude/index";
72+
~~~~~~~~~~~~~~~~~~~~~~~~
73+
!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
74+
export { cjs };
75+
export { mjs };
76+
export { type };
77+
==== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.mts (3 errors) ====
78+
// esm format file
79+
import * as cjs from "inner/cjs/exclude/index";
80+
~~~~~~~~~~~~~~~~~~~~~~~~~
81+
!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
82+
import * as mjs from "inner/mjs/exclude/index";
83+
~~~~~~~~~~~~~~~~~~~~~~~~~
84+
!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
85+
import * as type from "inner/js/exclude/index";
86+
~~~~~~~~~~~~~~~~~~~~~~~~
87+
!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
88+
export { cjs };
89+
export { mjs };
90+
export { type };
91+
==== tests/cases/conformance/node/allowJs/node_modules/inner/exclude/index.d.cts (3 errors) ====
92+
// cjs format file
93+
import * as cjs from "inner/cjs/exclude/index";
94+
~~~~~~~~~~~~~~~~~~~~~~~~~
95+
!!! error TS2307: Cannot find module 'inner/cjs/exclude/index' or its corresponding type declarations.
96+
import * as mjs from "inner/mjs/exclude/index";
97+
~~~~~~~~~~~~~~~~~~~~~~~~~
98+
!!! error TS2307: Cannot find module 'inner/mjs/exclude/index' or its corresponding type declarations.
99+
import * as type from "inner/js/exclude/index";
100+
~~~~~~~~~~~~~~~~~~~~~~~~
101+
!!! error TS2307: Cannot find module 'inner/js/exclude/index' or its corresponding type declarations.
102+
export { cjs };
103+
export { mjs };
104+
export { type };
105+
==== tests/cases/conformance/node/allowJs/package.json (0 errors) ====
106+
{
107+
"name": "package",
108+
"private": true,
109+
"type": "module"
110+
}
111+
==== tests/cases/conformance/node/allowJs/node_modules/inner/package.json (0 errors) ====
112+
{
113+
"name": "inner",
114+
"private": true,
115+
"exports": {
116+
"./cjs/*": "./*.cjs",
117+
"./cjs/exclude/*": null,
118+
"./mjs/*": "./*.mjs",
119+
"./mjs/exclude/*": null,
120+
"./js/*": "./*.js",
121+
"./js/exclude/*": null
122+
}
123+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//// [tests/cases/conformance/node/allowJs/nodeModulesAllowJsPackagePatternExportsExclude.ts] ////
2+
3+
//// [index.js]
4+
// esm format file
5+
import * as cjsi from "inner/cjs/exclude/index";
6+
import * as mjsi from "inner/mjs/exclude/index";
7+
import * as typei from "inner/js/exclude/index";
8+
cjsi;
9+
mjsi;
10+
typei;
11+
//// [index.mjs]
12+
// esm format file
13+
import * as cjsi from "inner/cjs/exclude/index";
14+
import * as mjsi from "inner/mjs/exclude/index";
15+
import * as typei from "inner/js/exclude/index";
16+
cjsi;
17+
mjsi;
18+
typei;
19+
//// [index.cjs]
20+
// cjs format file
21+
import * as cjsi from "inner/cjs/exclude/index";
22+
import * as mjsi from "inner/mjs/exclude/index";
23+
import * as typei from "inner/js/exclude/index";
24+
cjsi;
25+
mjsi;
26+
typei;
27+
//// [index.d.ts]
28+
// cjs format file
29+
import * as cjs from "inner/cjs/exclude/index";
30+
import * as mjs from "inner/mjs/exclude/index";
31+
import * as type from "inner/js/exclude/index";
32+
export { cjs };
33+
export { mjs };
34+
export { type };
35+
//// [index.d.mts]
36+
// esm format file
37+
import * as cjs from "inner/cjs/exclude/index";
38+
import * as mjs from "inner/mjs/exclude/index";
39+
import * as type from "inner/js/exclude/index";
40+
export { cjs };
41+
export { mjs };
42+
export { type };
43+
//// [index.d.cts]
44+
// cjs format file
45+
import * as cjs from "inner/cjs/exclude/index";
46+
import * as mjs from "inner/mjs/exclude/index";
47+
import * as type from "inner/js/exclude/index";
48+
export { cjs };
49+
export { mjs };
50+
export { type };
51+
//// [package.json]
52+
{
53+
"name": "package",
54+
"private": true,
55+
"type": "module"
56+
}
57+
//// [package.json]
58+
{
59+
"name": "inner",
60+
"private": true,
61+
"exports": {
62+
"./cjs/*": "./*.cjs",
63+
"./cjs/exclude/*": null,
64+
"./mjs/*": "./*.mjs",
65+
"./mjs/exclude/*": null,
66+
"./js/*": "./*.js",
67+
"./js/exclude/*": null
68+
}
69+
}
70+
71+
//// [index.js]
72+
// esm format file
73+
import * as cjsi from "inner/cjs/exclude/index";
74+
import * as mjsi from "inner/mjs/exclude/index";
75+
import * as typei from "inner/js/exclude/index";
76+
cjsi;
77+
mjsi;
78+
typei;
79+
//// [index.mjs]
80+
// esm format file
81+
import * as cjsi from "inner/cjs/exclude/index";
82+
import * as mjsi from "inner/mjs/exclude/index";
83+
import * as typei from "inner/js/exclude/index";
84+
cjsi;
85+
mjsi;
86+
typei;
87+
//// [index.cjs]
88+
"use strict";
89+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
90+
if (k2 === undefined) k2 = k;
91+
var desc = Object.getOwnPropertyDescriptor(m, k);
92+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
93+
desc = { enumerable: true, get: function() { return m[k]; } };
94+
}
95+
Object.defineProperty(o, k2, desc);
96+
}) : (function(o, m, k, k2) {
97+
if (k2 === undefined) k2 = k;
98+
o[k2] = m[k];
99+
}));
100+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
101+
Object.defineProperty(o, "default", { enumerable: true, value: v });
102+
}) : function(o, v) {
103+
o["default"] = v;
104+
});
105+
var __importStar = (this && this.__importStar) || function (mod) {
106+
if (mod && mod.__esModule) return mod;
107+
var result = {};
108+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
109+
__setModuleDefault(result, mod);
110+
return result;
111+
};
112+
Object.defineProperty(exports, "__esModule", { value: true });
113+
// cjs format file
114+
const cjsi = __importStar(require("inner/cjs/exclude/index"));
115+
const mjsi = __importStar(require("inner/mjs/exclude/index"));
116+
const typei = __importStar(require("inner/js/exclude/index"));
117+
cjsi;
118+
mjsi;
119+
typei;
120+
121+
122+
//// [index.d.ts]
123+
export {};
124+
//// [index.d.mts]
125+
export {};
126+
//// [index.d.cts]
127+
export {};

0 commit comments

Comments
 (0)