Skip to content

Commit e60665e

Browse files
authored
feat: support output.environment.nodePrefixForCoreModules (#8516)
1 parent 587b4bc commit e60665e

File tree

10 files changed

+132
-6
lines changed

10 files changed

+132
-6
lines changed

crates/node_binding/binding.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,7 @@ export interface RawEntryDynamicResult {
13351335
export interface RawEnvironment {
13361336
const?: boolean
13371337
arrowFunction?: boolean
1338+
nodePrefixForCoreModules?: boolean
13381339
}
13391340

13401341
export interface RawEvalDevToolModulePluginOptions {

crates/rspack_binding_options/src/options/raw_output.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,15 @@ impl From<RawCrossOriginLoading> for CrossOriginLoading {
4747
pub struct RawEnvironment {
4848
pub r#const: Option<bool>,
4949
pub arrow_function: Option<bool>,
50+
pub node_prefix_for_core_modules: Option<bool>,
5051
}
5152

5253
impl From<RawEnvironment> for Environment {
5354
fn from(value: RawEnvironment) -> Self {
5455
Self {
5556
r#const: value.r#const,
5657
arrow_function: value.arrow_function,
58+
node_prefix_for_core_modules: value.node_prefix_for_core_modules,
5759
}
5860
}
5961
}

crates/rspack_core/src/external_module.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,19 @@ impl ExternalModule {
272272
)
273273
}
274274
"node-commonjs" if let Some(request) = request => {
275+
let need_prefix = compilation
276+
.options
277+
.output
278+
.environment
279+
.supports_node_prefix_for_core_modules();
280+
275281
if compilation.options.output.module {
276282
chunk_init_fragments.push(
277283
NormalInitFragment::new(
278-
"import { createRequire as __WEBPACK_EXTERNAL_createRequire } from \"module\";\n"
279-
.to_string(),
284+
format!(
285+
"import {{ createRequire as __WEBPACK_EXTERNAL_createRequire }} from \"{}\";\n",
286+
if need_prefix { "node:module" } else { "module" }
287+
),
280288
InitFragmentStage::StageESMImports,
281289
0,
282290
InitFragmentKey::ModuleExternal("node-commonjs".to_string()),

crates/rspack_core/src/options/output.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ pub struct LibraryCustomUmdObject {
461461
pub struct Environment {
462462
pub r#const: Option<bool>,
463463
pub arrow_function: Option<bool>,
464+
pub node_prefix_for_core_modules: Option<bool>,
464465
}
465466

466467
impl Environment {
@@ -471,4 +472,8 @@ impl Environment {
471472
pub fn supports_arrow_function(&self) -> bool {
472473
self.arrow_function.unwrap_or_default()
473474
}
475+
476+
pub fn supports_node_prefix_for_core_modules(&self) -> bool {
477+
self.node_prefix_for_core_modules.unwrap_or_default()
478+
}
474479
}

crates/rspack_plugin_javascript/src/dependency/esm/external_module_dependency.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,15 @@ impl DependencyTemplate for ExternalModuleDependency {
3333
_source: &mut TemplateReplaceSource,
3434
code_generatable_context: &mut TemplateContext,
3535
) {
36+
let need_prefix = code_generatable_context
37+
.compilation
38+
.options
39+
.output
40+
.environment
41+
.supports_node_prefix_for_core_modules();
3642
let chunk_init_fragments = code_generatable_context.chunk_init_fragments();
3743
let fragment = ExternalModuleInitFragment::new(
38-
self.module.clone(),
44+
format!("{}{}", if need_prefix { "node:" } else { "" }, self.module),
3945
self.import_specifier.clone(),
4046
self.default_import.clone(),
4147
InitFragmentStage::StageConstants,

crates/rspack_plugin_javascript/src/plugin/api_plugin.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,26 @@ async fn compilation(
2828
#[plugin_hook(JavascriptModulesRenderModuleContent for APIPlugin)]
2929
fn render_module_content(
3030
&self,
31-
_compilation: &Compilation,
31+
compilation: &Compilation,
3232
module: &BoxModule,
3333
_source: &mut RenderSource,
3434
init_fragments: &mut ChunkInitFragments,
3535
) -> Result<()> {
3636
if let Some(build_info) = module.build_info()
3737
&& build_info.need_create_require
3838
{
39+
let need_prefix = compilation
40+
.options
41+
.output
42+
.environment
43+
.supports_node_prefix_for_core_modules();
44+
3945
init_fragments.push(
4046
NormalInitFragment::new(
41-
"import { createRequire as __WEBPACK_EXTERNAL_createRequire } from 'module';\n".to_string(),
47+
format!(
48+
"import {{ createRequire as __WEBPACK_EXTERNAL_createRequire }} from \"{}\";\n",
49+
if need_prefix { "node:module" } else { "module" }
50+
),
4251
InitFragmentStage::StageESMImports,
4352
0,
4453
InitFragmentKey::ModuleExternal("node-commonjs".to_string()),

packages/rspack-test-tools/tests/__snapshots__/Config.test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ export { a };
514514
`;
515515
516516
exports[`config config/library/modern-module-force-concaten step should pass: external module should bail out when bundling 1`] = `
517-
import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "module";
517+
import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "node:module";
518518
var __webpack_modules__ = ({
519519
"17": (function (module) {
520520
module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("path");
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import fs from "fs";
2+
3+
it(`should have/have not 'node:' prefix ${__filename}`, () => {
4+
const content = fs.readFileSync(__filename, "utf-8");
5+
6+
if (/bundle7\.js$/.test(__filename)) {
7+
expect(content).toContain("require(\"fs\");");
8+
} else if (/(bundle1\.mjs|bundle3\.mjs|bundle6\.mjs)$/.test(__filename)) {
9+
expect(content).toContain("from \"url\"");
10+
expect(content).toContain("from \"module\"");
11+
} else {
12+
expect(content).toContain("from \"node:url\"");
13+
expect(content).toContain("from \"node:module\"");
14+
}
15+
});
16+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = function () {
2+
return !process.version.startsWith("v10.");
3+
};
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/** @type {import("../../../../").Configuration} */
2+
module.exports = [
3+
{
4+
target: "node",
5+
experiments: {
6+
outputModule: true
7+
},
8+
output: {
9+
module: true,
10+
chunkFormat: "module"
11+
}
12+
},
13+
{
14+
target: "node14.17",
15+
experiments: {
16+
outputModule: true
17+
},
18+
output: {
19+
module: true,
20+
chunkFormat: "module"
21+
}
22+
},
23+
{
24+
target: "node14.18",
25+
experiments: {
26+
outputModule: true
27+
},
28+
output: {
29+
module: true,
30+
chunkFormat: "module"
31+
}
32+
},
33+
{
34+
target: "node15",
35+
experiments: {
36+
outputModule: true
37+
},
38+
output: {
39+
module: true,
40+
chunkFormat: "module"
41+
}
42+
},
43+
{
44+
target: "node16",
45+
experiments: {
46+
outputModule: true
47+
},
48+
output: {
49+
module: true,
50+
chunkFormat: "module"
51+
}
52+
},
53+
{
54+
target: "browserslist:node 14.18.0, node 16.0.0",
55+
experiments: {
56+
outputModule: true
57+
},
58+
output: {
59+
module: true,
60+
chunkFormat: "module"
61+
}
62+
},
63+
{
64+
target: "browserslist:node 14.18.0, node 15.0.0, node 16.0.0",
65+
experiments: {
66+
outputModule: true
67+
},
68+
output: {
69+
module: true,
70+
chunkFormat: "module"
71+
}
72+
},
73+
{
74+
target: "node"
75+
}
76+
];

0 commit comments

Comments
 (0)