Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions lib/APIPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,11 @@ class APIPlugin {
PLUGIN_NAME,
(source, module, renderContext) => {
if (/** @type {BuildInfo} */ (module.buildInfo).needCreateRequire) {
const needPrefix =
renderContext.runtimeTemplate.supportNodePrefixForCoreModules();
const chunkInitFragments = [
new InitFragment(
`import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "${
needPrefix ? "node:" : ""
}module";\n`,
`import { createRequire as __WEBPACK_EXTERNAL_createRequire } from ${renderContext.runtimeTemplate.renderNodePrefixForCoreModule(
"module"
)};\n`,
InitFragment.STAGE_HARMONY_IMPORTS,
0,
"external module node-commonjs"
Expand Down
27 changes: 12 additions & 15 deletions lib/ExternalModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,21 +125,24 @@ const getSourceForCommonJsExternal = (moduleAndSpecifiers) => {
};

/**
* @param {string|string[]} moduleAndSpecifiers the module request
* @param {string} importMetaName import.meta name
* @param {boolean} needPrefix need to use `node:` prefix for `module` import
* @param {string | string[]} moduleAndSpecifiers the module request
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @returns {SourceData} the generated source
*/
const getSourceForCommonJsExternalInNodeModule = (
moduleAndSpecifiers,
importMetaName,
needPrefix
runtimeTemplate
) => {
const importMetaName =
/** @type {string} */
(runtimeTemplate.outputOptions.importMetaName);

// /** @type {boolean} */
// (runtimeTemplate.supportNodePrefixForCoreModules())

const chunkInitFragments = [
new InitFragment(
`import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "${
needPrefix ? "node:" : ""
}module";\n`,
`import { createRequire as __WEBPACK_EXTERNAL_createRequire } from ${runtimeTemplate.renderNodePrefixForCoreModule("module")};\n`,
InitFragment.STAGE_HARMONY_IMPORTS,
0,
"external module node-commonjs"
Expand Down Expand Up @@ -763,13 +766,7 @@ class ExternalModule extends Module {
return getSourceForCommonJsExternal(request);
case "node-commonjs":
return /** @type {BuildInfo} */ (this.buildInfo).javascriptModule
? getSourceForCommonJsExternalInNodeModule(
request,
/** @type {string} */
(runtimeTemplate.outputOptions.importMetaName),
/** @type {boolean} */
(runtimeTemplate.supportNodePrefixForCoreModules())
)
? getSourceForCommonJsExternalInNodeModule(request, runtimeTemplate)
: getSourceForCommonJsExternal(request);
case "amd":
case "amd-require":
Expand Down
24 changes: 18 additions & 6 deletions lib/NodeStuffPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ class NodeStuffPlugin {
.tap(PLUGIN_NAME, (expr) => {
const dep = new CachedConstDependency(
JSON.stringify(fn(parser.state.module)),
/** @type {Range} */ (expr.range),
/** @type {Range} */
(expr.range),
expressionName
);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
Expand Down Expand Up @@ -186,12 +187,17 @@ class NodeStuffPlugin {
"__filename is a Node.js feature and isn't available in browsers."
);
break;
case "node-module":
case "node-module": {
const importMetaName =
/** @type {string} */
(compilation.outputOptions.importMetaName);

setUrlModuleConstant(
"__filename",
(functionName) => `${functionName}(import.meta.url)`
(functionName) => `${functionName}(${importMetaName}.url)`
);
break;
}
case true:
setModuleConstant("__filename", (module) =>
relative(
Expand Down Expand Up @@ -223,13 +229,18 @@ class NodeStuffPlugin {
"__dirname is a Node.js feature and isn't available in browsers."
);
break;
case "node-module":
case "node-module": {
const importMetaName =
/** @type {string} */
(compilation.outputOptions.importMetaName);

setUrlModuleConstant(
"__dirname",
(functionName) =>
`${functionName}(import.meta.url + "/..").slice(0, -1)`
`${functionName}(${importMetaName}.url + "/..").slice(0, -1)`
);
break;
}
case true:
setModuleConstant("__dirname", (module) =>
relative(
Expand All @@ -246,7 +257,8 @@ class NodeStuffPlugin {
.tap(PLUGIN_NAME, (expr) => {
if (!parser.state.module) return;
return evaluateToString(
/** @type {string} */ (parser.state.module.context)
/** @type {string} */
(parser.state.module.context)
)(expr);
});
}
Expand Down
10 changes: 10 additions & 0 deletions lib/RuntimeTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@ class RuntimeTemplate {
return this.outputOptions.environment.nodePrefixForCoreModules;
}

/**
* @param {string} mod a module
* @returns {string} a module with `node:` prefix when supported, otherwise an original name
*/
renderNodePrefixForCoreModule(mod) {
return this.outputOptions.environment.nodePrefixForCoreModules
? `"node:${mod}"`
: `"${mod}"`;
}

/**
* @param {string} returnValue return value
* @param {string} args arguments
Expand Down
28 changes: 15 additions & 13 deletions lib/node/ReadFileChunkLoadingRuntimeModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const { getUndoPath } = require("../util/identifier");
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */

class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
Expand All @@ -36,15 +37,16 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
* @private
* @param {Chunk} chunk chunk
* @param {string} rootOutputDir root output directory
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @returns {string} generated code
*/
_generateBaseUri(chunk, rootOutputDir) {
_generateBaseUri(chunk, rootOutputDir, runtimeTemplate) {
const options = chunk.getEntryOptions();
if (options && options.baseUri) {
return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
}

return `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${
return `${RuntimeGlobals.baseURI} = require(${runtimeTemplate.renderNodePrefixForCoreModule("url")}).pathToFileURL(${
rootOutputDir
? `__dirname + ${JSON.stringify(`/${rootOutputDir}`)}`
: "__filename"
Expand Down Expand Up @@ -99,7 +101,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {

return Template.asString([
withBaseURI
? this._generateBaseUri(chunk, rootOutputDir)
? this._generateBaseUri(chunk, rootOutputDir, runtimeTemplate)
: "// no baseURI",
"",
"// object to store loaded chunks",
Expand Down Expand Up @@ -171,17 +173,17 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
"var promise = new Promise(function(resolve, reject) {",
Template.indent([
"installedChunkData = installedChunks[chunkId] = [resolve, reject];",
`var filename = require('path').join(__dirname, ${JSON.stringify(
`var filename = require(${runtimeTemplate.renderNodePrefixForCoreModule("path")}).join(__dirname, ${JSON.stringify(
rootOutputDir
)} + ${
RuntimeGlobals.getChunkScriptFilename
}(chunkId));`,
"require('fs').readFile(filename, 'utf-8', function(err, content) {",
`require(${runtimeTemplate.renderNodePrefixForCoreModule("fs")}).readFile(filename, 'utf-8', function(err, content) {`,
Template.indent([
"if(err) return reject(err);",
"var chunk = {};",
"require('vm').runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\n})', filename)" +
"(chunk, require, require('path').dirname(filename), filename);",
`require(${runtimeTemplate.renderNodePrefixForCoreModule("vm")}).runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\n})', filename)` +
`(chunk, require, require(${runtimeTemplate.renderNodePrefixForCoreModule("path")}).dirname(filename), filename);`,
"installChunk(chunk);"
]),
"});"
Expand Down Expand Up @@ -215,15 +217,15 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
Template.indent([
"return new Promise(function(resolve, reject) {",
Template.indent([
`var filename = require('path').join(__dirname, ${JSON.stringify(
`var filename = require(${runtimeTemplate.renderNodePrefixForCoreModule("path")}).join(__dirname, ${JSON.stringify(
rootOutputDir
)} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId));`,
"require('fs').readFile(filename, 'utf-8', function(err, content) {",
`require(${runtimeTemplate.renderNodePrefixForCoreModule("fs")}).readFile(filename, 'utf-8', function(err, content) {`,
Template.indent([
"if(err) return reject(err);",
"var update = {};",
"require('vm').runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\n})', filename)" +
"(update, require, require('path').dirname(filename), filename);",
`require(${runtimeTemplate.renderNodePrefixForCoreModule("vm")}).runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\n})', filename)` +
`(update, require, require(${runtimeTemplate.renderNodePrefixForCoreModule("path")}).dirname(filename), filename);`,
"var updatedModules = update.modules;",
"var runtime = update.runtime;",
"for(var moduleId in updatedModules) {",
Expand Down Expand Up @@ -255,10 +257,10 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
Template.indent([
"return new Promise(function(resolve, reject) {",
Template.indent([
`var filename = require('path').join(__dirname, ${JSON.stringify(
`var filename = require(${runtimeTemplate.renderNodePrefixForCoreModule("path")}).join(__dirname, ${JSON.stringify(
rootOutputDir
)} + ${RuntimeGlobals.getUpdateManifestFilename}());`,
"require('fs').readFile(filename, 'utf-8', function(err, content) {",
`require(${runtimeTemplate.renderNodePrefixForCoreModule("fs")}).readFile(filename, 'utf-8', function(err, content) {`,
Template.indent([
"if(err) {",
Template.indent([
Expand Down
4 changes: 2 additions & 2 deletions lib/node/ReadFileCompileAsyncWasmPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ class ReadFileCompileAsyncWasmPlugin {
Template.indent([
"try {",
Template.indent([
"var { readFile } = require('fs');",
"var { join } = require('path');",
`var { readFile } = require(${compilation.runtimeTemplate.renderNodePrefixForCoreModule("fs")});`,
`var { join } = require(${compilation.runtimeTemplate.renderNodePrefixForCoreModule("path")});`,
"",
`readFile(join(__dirname, ${path}), function(err, buffer){`,
Template.indent([
Expand Down
4 changes: 2 additions & 2 deletions lib/node/ReadFileCompileWasmPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ class ReadFileCompileWasmPlugin {
Template.asString([
"new Promise(function (resolve, reject) {",
Template.indent([
"var { readFile } = require('fs');",
"var { join } = require('path');",
`var { readFile } = require(${compilation.runtimeTemplate.renderNodePrefixForCoreModule("fs")});`,
`var { join } = require(${compilation.runtimeTemplate.renderNodePrefixForCoreModule("path")});`,
"",
"try {",
Template.indent([
Expand Down
8 changes: 5 additions & 3 deletions lib/node/RequireChunkLoadingRuntimeModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const { getUndoPath } = require("../util/identifier");
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */

class RequireChunkLoadingRuntimeModule extends RuntimeModule {
Expand All @@ -36,15 +37,16 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule {
* @private
* @param {Chunk} chunk chunk
* @param {string} rootOutputDir root output directory
* @param {RuntimeTemplate} runtimeTemplate the runtime template
* @returns {string} generated code
*/
_generateBaseUri(chunk, rootOutputDir) {
_generateBaseUri(chunk, rootOutputDir, runtimeTemplate) {
const options = chunk.getEntryOptions();
if (options && options.baseUri) {
return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
}

return `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${
return `${RuntimeGlobals.baseURI} = require(${runtimeTemplate.renderNodePrefixForCoreModule("url")}).pathToFileURL(${
rootOutputDir !== "./"
? `__dirname + ${JSON.stringify(`/${rootOutputDir}`)}`
: "__filename"
Expand Down Expand Up @@ -99,7 +101,7 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule {

return Template.asString([
withBaseURI
? this._generateBaseUri(chunk, rootOutputDir)
? this._generateBaseUri(chunk, rootOutputDir, runtimeTemplate)
: "// no baseURI",
"",
"// object to store loaded chunks",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
"devDependencies": {
"@babel/core": "^7.27.1",
"@babel/preset-react": "^7.27.1",
"@codspeed/tinybench-plugin": "^4.0.1",
"@codspeed/core": "^4.0.1",
"@eslint/js": "^9.29.0",
"@eslint/markdown": "^7.0.0",
"@stylistic/eslint-plugin": "^5.0.0",
Expand Down
Loading
Loading