Skip to content

Commit 1cee973

Browse files
authored
Properly support scoped package self name lookups (#46212)
1 parent 47cd4d3 commit 1cee973

10 files changed

+297
-2
lines changed

src/compiler/moduleNameResolver.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1724,11 +1724,15 @@ namespace ts {
17241724
if (!scope || !scope.packageJsonContent.exports) {
17251725
return undefined;
17261726
}
1727+
if (typeof scope.packageJsonContent.name !== "string") {
1728+
return undefined;
1729+
}
17271730
const parts = getPathComponents(moduleName); // unrooted paths should have `""` as their 0th entry
1728-
if (scope.packageJsonContent.name !== parts[1]) {
1731+
const nameParts = getPathComponents(scope.packageJsonContent.name);
1732+
if (!every(nameParts, (p, i) => parts[i] === p)) {
17291733
return undefined;
17301734
}
1731-
const trailingParts = parts.slice(2);
1735+
const trailingParts = parts.slice(nameParts.length);
17321736
return loadModuleFromExports(scope, extensions, !length(trailingParts) ? "." : `.${directorySeparator}${trailingParts.join(directorySeparator)}`, state, cache, redirectedReference);
17331737
}
17341738

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
tests/cases/conformance/node/index.cts(2,23): error TS1471: Module '@scope/package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
2+
3+
4+
==== tests/cases/conformance/node/index.ts (0 errors) ====
5+
// esm format file
6+
import * as self from "@scope/package";
7+
self;
8+
==== tests/cases/conformance/node/index.mts (0 errors) ====
9+
// esm format file
10+
import * as self from "@scope/package";
11+
self;
12+
==== tests/cases/conformance/node/index.cts (1 errors) ====
13+
// cjs format file
14+
import * as self from "@scope/package";
15+
~~~~~~~~~~~~~~~~
16+
!!! error TS1471: Module '@scope/package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
17+
self;
18+
==== tests/cases/conformance/node/package.json (0 errors) ====
19+
{
20+
"name": "@scope/package",
21+
"private": true,
22+
"type": "module",
23+
"exports": "./index.js"
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//// [tests/cases/conformance/node/nodePackageSelfNameScoped.ts] ////
2+
3+
//// [index.ts]
4+
// esm format file
5+
import * as self from "@scope/package";
6+
self;
7+
//// [index.mts]
8+
// esm format file
9+
import * as self from "@scope/package";
10+
self;
11+
//// [index.cts]
12+
// cjs format file
13+
import * as self from "@scope/package";
14+
self;
15+
//// [package.json]
16+
{
17+
"name": "@scope/package",
18+
"private": true,
19+
"type": "module",
20+
"exports": "./index.js"
21+
}
22+
23+
//// [index.js]
24+
// esm format file
25+
import * as self from "@scope/package";
26+
self;
27+
//// [index.mjs]
28+
// esm format file
29+
import * as self from "@scope/package";
30+
self;
31+
//// [index.cjs]
32+
"use strict";
33+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
34+
if (k2 === undefined) k2 = k;
35+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
36+
}) : (function(o, m, k, k2) {
37+
if (k2 === undefined) k2 = k;
38+
o[k2] = m[k];
39+
}));
40+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
41+
Object.defineProperty(o, "default", { enumerable: true, value: v });
42+
}) : function(o, v) {
43+
o["default"] = v;
44+
});
45+
var __importStar = (this && this.__importStar) || function (mod) {
46+
if (mod && mod.__esModule) return mod;
47+
var result = {};
48+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
49+
__setModuleDefault(result, mod);
50+
return result;
51+
};
52+
Object.defineProperty(exports, "__esModule", { value: true });
53+
// cjs format file
54+
const self = __importStar(require("@scope/package"));
55+
self;
56+
57+
58+
//// [index.d.ts]
59+
export {};
60+
//// [index.d.mts]
61+
export {};
62+
//// [index.d.cts]
63+
export {};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/conformance/node/index.ts ===
2+
// esm format file
3+
import * as self from "@scope/package";
4+
>self : Symbol(self, Decl(index.ts, 1, 6))
5+
6+
self;
7+
>self : Symbol(self, Decl(index.ts, 1, 6))
8+
9+
=== tests/cases/conformance/node/index.mts ===
10+
// esm format file
11+
import * as self from "@scope/package";
12+
>self : Symbol(self, Decl(index.mts, 1, 6))
13+
14+
self;
15+
>self : Symbol(self, Decl(index.mts, 1, 6))
16+
17+
=== tests/cases/conformance/node/index.cts ===
18+
// cjs format file
19+
import * as self from "@scope/package";
20+
>self : Symbol(self, Decl(index.cts, 1, 6))
21+
22+
self;
23+
>self : Symbol(self, Decl(index.cts, 1, 6))
24+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/conformance/node/index.ts ===
2+
// esm format file
3+
import * as self from "@scope/package";
4+
>self : typeof self
5+
6+
self;
7+
>self : typeof self
8+
9+
=== tests/cases/conformance/node/index.mts ===
10+
// esm format file
11+
import * as self from "@scope/package";
12+
>self : typeof self
13+
14+
self;
15+
>self : typeof self
16+
17+
=== tests/cases/conformance/node/index.cts ===
18+
// cjs format file
19+
import * as self from "@scope/package";
20+
>self : typeof self
21+
22+
self;
23+
>self : typeof self
24+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
tests/cases/conformance/node/index.cts(2,23): error TS1471: Module '@scope/package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
2+
3+
4+
==== tests/cases/conformance/node/index.ts (0 errors) ====
5+
// esm format file
6+
import * as self from "@scope/package";
7+
self;
8+
==== tests/cases/conformance/node/index.mts (0 errors) ====
9+
// esm format file
10+
import * as self from "@scope/package";
11+
self;
12+
==== tests/cases/conformance/node/index.cts (1 errors) ====
13+
// cjs format file
14+
import * as self from "@scope/package";
15+
~~~~~~~~~~~~~~~~
16+
!!! error TS1471: Module '@scope/package' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
17+
self;
18+
==== tests/cases/conformance/node/package.json (0 errors) ====
19+
{
20+
"name": "@scope/package",
21+
"private": true,
22+
"type": "module",
23+
"exports": "./index.js"
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//// [tests/cases/conformance/node/nodePackageSelfNameScoped.ts] ////
2+
3+
//// [index.ts]
4+
// esm format file
5+
import * as self from "@scope/package";
6+
self;
7+
//// [index.mts]
8+
// esm format file
9+
import * as self from "@scope/package";
10+
self;
11+
//// [index.cts]
12+
// cjs format file
13+
import * as self from "@scope/package";
14+
self;
15+
//// [package.json]
16+
{
17+
"name": "@scope/package",
18+
"private": true,
19+
"type": "module",
20+
"exports": "./index.js"
21+
}
22+
23+
//// [index.js]
24+
// esm format file
25+
import * as self from "@scope/package";
26+
self;
27+
//// [index.mjs]
28+
// esm format file
29+
import * as self from "@scope/package";
30+
self;
31+
//// [index.cjs]
32+
"use strict";
33+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
34+
if (k2 === undefined) k2 = k;
35+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
36+
}) : (function(o, m, k, k2) {
37+
if (k2 === undefined) k2 = k;
38+
o[k2] = m[k];
39+
}));
40+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
41+
Object.defineProperty(o, "default", { enumerable: true, value: v });
42+
}) : function(o, v) {
43+
o["default"] = v;
44+
});
45+
var __importStar = (this && this.__importStar) || function (mod) {
46+
if (mod && mod.__esModule) return mod;
47+
var result = {};
48+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
49+
__setModuleDefault(result, mod);
50+
return result;
51+
};
52+
Object.defineProperty(exports, "__esModule", { value: true });
53+
// cjs format file
54+
const self = __importStar(require("@scope/package"));
55+
self;
56+
57+
58+
//// [index.d.ts]
59+
export {};
60+
//// [index.d.mts]
61+
export {};
62+
//// [index.d.cts]
63+
export {};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/conformance/node/index.ts ===
2+
// esm format file
3+
import * as self from "@scope/package";
4+
>self : Symbol(self, Decl(index.ts, 1, 6))
5+
6+
self;
7+
>self : Symbol(self, Decl(index.ts, 1, 6))
8+
9+
=== tests/cases/conformance/node/index.mts ===
10+
// esm format file
11+
import * as self from "@scope/package";
12+
>self : Symbol(self, Decl(index.mts, 1, 6))
13+
14+
self;
15+
>self : Symbol(self, Decl(index.mts, 1, 6))
16+
17+
=== tests/cases/conformance/node/index.cts ===
18+
// cjs format file
19+
import * as self from "@scope/package";
20+
>self : Symbol(self, Decl(index.cts, 1, 6))
21+
22+
self;
23+
>self : Symbol(self, Decl(index.cts, 1, 6))
24+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/conformance/node/index.ts ===
2+
// esm format file
3+
import * as self from "@scope/package";
4+
>self : typeof self
5+
6+
self;
7+
>self : typeof self
8+
9+
=== tests/cases/conformance/node/index.mts ===
10+
// esm format file
11+
import * as self from "@scope/package";
12+
>self : typeof self
13+
14+
self;
15+
>self : typeof self
16+
17+
=== tests/cases/conformance/node/index.cts ===
18+
// cjs format file
19+
import * as self from "@scope/package";
20+
>self : typeof self
21+
22+
self;
23+
>self : typeof self
24+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// @module: node12,nodenext
2+
// @declaration: true
3+
// @filename: index.ts
4+
// esm format file
5+
import * as self from "@scope/package";
6+
self;
7+
// @filename: index.mts
8+
// esm format file
9+
import * as self from "@scope/package";
10+
self;
11+
// @filename: index.cts
12+
// cjs format file
13+
import * as self from "@scope/package";
14+
self;
15+
// @filename: package.json
16+
{
17+
"name": "@scope/package",
18+
"private": true,
19+
"type": "module",
20+
"exports": "./index.js"
21+
}

0 commit comments

Comments
 (0)