Skip to content

Commit 0a3508a

Browse files
authored
Fix module_resolution: "nodenext" with mjs or cjs (#71635)
A regression from vercel/turborepo#8748 Closes PACK-3312 Previously, it treated imports to `something.mjs` as importing `something.mts` with a fallback to `something.js`. But it should obviously instead fallback to the original extension `mjs`, which is also what tsc does: ``` Found 'package.json' at 'input/package.json'. ======== Resolving module './src/foo.mjs' from 'input/index.js'. ======== Explicitly specified module resolution kind: 'NodeNext'. Resolving in CJS mode with conditions 'require', 'types', 'node'. Loading module as file / folder, candidate module location 'input/src/foo.mjs', target file types: TypeScript, JavaScript, Declaration. File name 'input/src/foo.mjs' has a '.mjs' extension - stripping it. File 'input/src/foo.mts' does not exist. File 'input/src/foo.d.mts' does not exist. File 'input/src/foo.mjs' does not exist. File 'input/src/foo.mjs.ts' does not exist. File 'input/src/foo.mjs.tsx' does not exist. File 'input/src/foo.mjs.d.ts' does not exist. File 'input/src/foo.mjs.js' does not exist. File 'input/src/foo.mjs.jsx' does not exist. Directory 'input/src/foo.mjs' does not exist, skipping all lookups in it. ======== Module name './src/foo.mjs' was not resolved. ======== ```
1 parent 9fb618f commit 0a3508a

File tree

14 files changed

+55
-33
lines changed

14 files changed

+55
-33
lines changed

turbopack/crates/turbopack-core/src/resolve/mod.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,41 +2006,41 @@ async fn resolve_relative_request(
20062006

20072007
if options_value.enable_typescript_with_output_extension {
20082008
new_path.replace_final_constants(&|c: &RcStr| -> Option<Pattern> {
2009-
let result = match c.rsplit_once(".") {
2010-
Some((base, "js")) => Some((
2009+
let (base, replacement) = match c.rsplit_once(".") {
2010+
Some((base, "js")) => (
20112011
base,
20122012
vec![
20132013
Pattern::Constant(".ts".into()),
20142014
Pattern::Constant(".tsx".into()),
20152015
Pattern::Constant(".js".into()),
20162016
],
2017-
)),
2018-
Some((base, "mjs")) => Some((
2017+
),
2018+
Some((base, "mjs")) => (
20192019
base,
20202020
vec![
20212021
Pattern::Constant(".mts".into()),
2022-
Pattern::Constant(".js".into()),
2022+
Pattern::Constant(".mjs".into()),
20232023
],
2024-
)),
2025-
Some((base, "cjs")) => Some((
2024+
),
2025+
Some((base, "cjs")) => (
20262026
base,
20272027
vec![
20282028
Pattern::Constant(".cts".into()),
2029-
Pattern::Constant(".js".into()),
2029+
Pattern::Constant(".cjs".into()),
20302030
],
2031-
)),
2032-
_ => None,
2033-
};
2034-
result.map(|(base, replacement)| {
2035-
if base.is_empty() {
2036-
Pattern::Alternatives(replacement)
2037-
} else {
2038-
Pattern::Concatenation(vec![
2039-
Pattern::Constant(base.into()),
2040-
Pattern::Alternatives(replacement),
2041-
])
2031+
),
2032+
_ => {
2033+
return None;
20422034
}
2043-
})
2035+
};
2036+
if base.is_empty() {
2037+
Some(Pattern::Alternatives(replacement))
2038+
} else {
2039+
Some(Pattern::Concatenation(vec![
2040+
Pattern::Constant(base.into()),
2041+
Pattern::Alternatives(replacement),
2042+
]))
2043+
}
20442044
});
20452045
new_path.normalize();
20462046
}
Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
import foo from "./src/foo.js";
2-
import bar from "./src/bar.js";
3-
import fooEsm from "./src/foo-esm.mjs";
4-
import fooCjs from "./src/foo-cjs.cjs";
2+
import fileTsx from "./src/file-tsx.js";
3+
import fileMts from "./src/file-mts.mjs";
4+
import fileCts from "./src/file-cts.cjs";
5+
import fileMjs from "./src/file-mjs.mjs";
6+
import fileCjs from "./src/file-cjs.cjs";
57

68
it("should correctly resolve explicit extensions with nodenext", () => {
7-
expect(foo).toBe("foo");
8-
expect(bar).toBe("bar");
9-
expect(fooEsm).toBe("fooEsm");
10-
expect(fooCjs).toBe("fooCjs");
9+
expect(foo).toBe("foo.ts");
10+
expect(fileTsx).toBe("file-tsx");
11+
expect(fileMts).toBe("file-mts");
12+
expect(fileCts).toBe("file-cts");
13+
expect(fileMjs).toBe("file-mjs");
14+
expect(fileCjs).toBe("file-cjs");
1115
});
16+
17+
// import fooButton from "foo/button";
18+
19+
// it("should correctly resolve explicit extensions with nodenext", () => {
20+
// expect(fooButton).toBe("button");
21+
// });

turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-nodenext/input/node_modules/foo/package.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-nodenext/input/node_modules/foo/source.mjs

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-nodenext/input/src/bar.tsx

Lines changed: 0 additions & 1 deletion
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = 'file-cjs'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = "file-cts";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default 'file-mjs'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default "file-mts";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default "file-tsx";

0 commit comments

Comments
 (0)