mirror of https://github.com/webpack/webpack.git
fix: support `__non_webpack_require__` for ES modules
This commit is contained in:
parent
df204b5f71
commit
930785fb00
|
@ -5,7 +5,9 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const InitFragment = require("./InitFragment");
|
const {
|
||||||
|
getExternalModuleNodeCommonjsInitFragment
|
||||||
|
} = require("./ExternalModule");
|
||||||
const {
|
const {
|
||||||
JAVASCRIPT_MODULE_TYPE_AUTO,
|
JAVASCRIPT_MODULE_TYPE_AUTO,
|
||||||
JAVASCRIPT_MODULE_TYPE_DYNAMIC,
|
JAVASCRIPT_MODULE_TYPE_DYNAMIC,
|
||||||
|
@ -128,8 +130,6 @@ function getReplacements() {
|
||||||
|
|
||||||
const PLUGIN_NAME = "APIPlugin";
|
const PLUGIN_NAME = "APIPlugin";
|
||||||
|
|
||||||
const moduleCreateRequire = "__WEBPACK_EXTERNAL_createRequire";
|
|
||||||
|
|
||||||
class APIPlugin {
|
class APIPlugin {
|
||||||
/**
|
/**
|
||||||
* Apply the plugin
|
* Apply the plugin
|
||||||
|
@ -140,14 +140,14 @@ class APIPlugin {
|
||||||
compiler.hooks.compilation.tap(
|
compiler.hooks.compilation.tap(
|
||||||
PLUGIN_NAME,
|
PLUGIN_NAME,
|
||||||
(compilation, { normalModuleFactory }) => {
|
(compilation, { normalModuleFactory }) => {
|
||||||
const importMetaName = compilation.outputOptions.importMetaName;
|
|
||||||
const moduleOutput = compilation.options.output.module;
|
const moduleOutput = compilation.options.output.module;
|
||||||
const nodeTarget = compiler.platform.node;
|
const nodeTarget = compiler.platform.node;
|
||||||
const nodeEsm = moduleOutput && nodeTarget;
|
const nodeEsm = moduleOutput && nodeTarget;
|
||||||
|
|
||||||
const REPLACEMENTS = getReplacements();
|
const REPLACEMENTS = getReplacements();
|
||||||
if (nodeEsm) {
|
if (nodeEsm) {
|
||||||
REPLACEMENTS.__non_webpack_require__.expr = `${moduleCreateRequire}(${importMetaName}.url)`;
|
REPLACEMENTS.__non_webpack_require__.expr =
|
||||||
|
"__WEBPACK_EXTERNAL_createRequire_require";
|
||||||
}
|
}
|
||||||
|
|
||||||
compilation.dependencyTemplates.set(
|
compilation.dependencyTemplates.set(
|
||||||
|
@ -179,13 +179,8 @@ class APIPlugin {
|
||||||
(source, module, renderContext) => {
|
(source, module, renderContext) => {
|
||||||
if (/** @type {BuildInfo} */ (module.buildInfo).needCreateRequire) {
|
if (/** @type {BuildInfo} */ (module.buildInfo).needCreateRequire) {
|
||||||
const chunkInitFragments = [
|
const chunkInitFragments = [
|
||||||
new InitFragment(
|
getExternalModuleNodeCommonjsInitFragment(
|
||||||
`import { createRequire as ${moduleCreateRequire} } from ${renderContext.runtimeTemplate.renderNodePrefixForCoreModule(
|
renderContext.runtimeTemplate
|
||||||
"module"
|
|
||||||
)};\n`,
|
|
||||||
InitFragment.STAGE_HARMONY_IMPORTS,
|
|
||||||
0,
|
|
||||||
"external module node-commonjs"
|
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,23 @@ const getSourceForCommonJsExternal = (moduleAndSpecifiers) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {RuntimeTemplate} runtimeTemplate the runtime template
|
||||||
|
* @returns {InitFragment<ChunkRenderContext>} code
|
||||||
|
*/
|
||||||
|
const getExternalModuleNodeCommonjsInitFragment = (runtimeTemplate) => {
|
||||||
|
const importMetaName = runtimeTemplate.outputOptions.importMetaName;
|
||||||
|
|
||||||
|
return new InitFragment(
|
||||||
|
`import { createRequire as __WEBPACK_EXTERNAL_createRequire } from ${runtimeTemplate.renderNodePrefixForCoreModule(
|
||||||
|
"module"
|
||||||
|
)};\n${runtimeTemplate.renderConst()} __WEBPACK_EXTERNAL_createRequire_require = __WEBPACK_EXTERNAL_createRequire(${importMetaName}.url);\n`,
|
||||||
|
InitFragment.STAGE_HARMONY_IMPORTS,
|
||||||
|
0,
|
||||||
|
"external module node-commonjs"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string | string[]} moduleAndSpecifiers the module request
|
* @param {string | string[]} moduleAndSpecifiers the module request
|
||||||
* @param {RuntimeTemplate} runtimeTemplate the runtime template
|
* @param {RuntimeTemplate} runtimeTemplate the runtime template
|
||||||
|
@ -137,19 +154,13 @@ const getSourceForCommonJsExternalInNodeModule = (
|
||||||
moduleAndSpecifiers,
|
moduleAndSpecifiers,
|
||||||
runtimeTemplate
|
runtimeTemplate
|
||||||
) => {
|
) => {
|
||||||
const importMetaName = runtimeTemplate.outputOptions.importMetaName;
|
|
||||||
const chunkInitFragments = [
|
const chunkInitFragments = [
|
||||||
new InitFragment(
|
getExternalModuleNodeCommonjsInitFragment(runtimeTemplate)
|
||||||
`import { createRequire as __WEBPACK_EXTERNAL_createRequire } from ${runtimeTemplate.renderNodePrefixForCoreModule("module")};\n`,
|
|
||||||
InitFragment.STAGE_HARMONY_IMPORTS,
|
|
||||||
0,
|
|
||||||
"external module node-commonjs"
|
|
||||||
)
|
|
||||||
];
|
];
|
||||||
if (!Array.isArray(moduleAndSpecifiers)) {
|
if (!Array.isArray(moduleAndSpecifiers)) {
|
||||||
return {
|
return {
|
||||||
chunkInitFragments,
|
chunkInitFragments,
|
||||||
expression: `__WEBPACK_EXTERNAL_createRequire(${importMetaName}.url)(${JSON.stringify(
|
expression: `__WEBPACK_EXTERNAL_createRequire_require(${JSON.stringify(
|
||||||
moduleAndSpecifiers
|
moduleAndSpecifiers
|
||||||
)})`
|
)})`
|
||||||
};
|
};
|
||||||
|
@ -157,7 +168,7 @@ const getSourceForCommonJsExternalInNodeModule = (
|
||||||
const moduleName = moduleAndSpecifiers[0];
|
const moduleName = moduleAndSpecifiers[0];
|
||||||
return {
|
return {
|
||||||
chunkInitFragments,
|
chunkInitFragments,
|
||||||
expression: `__WEBPACK_EXTERNAL_createRequire(${importMetaName}.url)(${JSON.stringify(
|
expression: `__WEBPACK_EXTERNAL_createRequire_require(${JSON.stringify(
|
||||||
moduleName
|
moduleName
|
||||||
)})${propertyAccess(moduleAndSpecifiers, 1)}`
|
)})${propertyAccess(moduleAndSpecifiers, 1)}`
|
||||||
};
|
};
|
||||||
|
@ -1039,9 +1050,7 @@ class ExternalModule extends Module {
|
||||||
scope.registerRawExport(specifier, finalName);
|
scope.registerRawExport(specifier, finalName);
|
||||||
}
|
}
|
||||||
} else if (concatenationScope) {
|
} else if (concatenationScope) {
|
||||||
sourceString = `${
|
sourceString = `${runtimeTemplate.renderConst()} ${ConcatenationScope.NAMESPACE_OBJECT_EXPORT} = ${sourceString};`;
|
||||||
runtimeTemplate.supportsConst() ? "const" : "var"
|
|
||||||
} ${ConcatenationScope.NAMESPACE_OBJECT_EXPORT} = ${sourceString};`;
|
|
||||||
concatenationScope.registerNamespaceExport(
|
concatenationScope.registerNamespaceExport(
|
||||||
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
||||||
);
|
);
|
||||||
|
@ -1145,3 +1154,5 @@ makeSerializable(ExternalModule, "webpack/lib/ExternalModule");
|
||||||
|
|
||||||
module.exports = ExternalModule;
|
module.exports = ExternalModule;
|
||||||
module.exports.ModuleExternalInitFragment = ModuleExternalInitFragment;
|
module.exports.ModuleExternalInitFragment = ModuleExternalInitFragment;
|
||||||
|
module.exports.getExternalModuleNodeCommonjsInitFragment =
|
||||||
|
getExternalModuleNodeCommonjsInitFragment;
|
||||||
|
|
|
@ -168,6 +168,13 @@ class RuntimeTemplate {
|
||||||
: `"${mod}"`;
|
: `"${mod}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {"const" | "var"} return `const` when it is supported, otherwise `var`
|
||||||
|
*/
|
||||||
|
renderConst() {
|
||||||
|
return this.supportsConst() ? "const" : "var";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} returnValue return value
|
* @param {string} returnValue return value
|
||||||
* @param {string} args arguments
|
* @param {string} args arguments
|
||||||
|
|
|
@ -612,7 +612,7 @@ class AssetGenerator extends Generator {
|
||||||
);
|
);
|
||||||
|
|
||||||
return new RawSource(
|
return new RawSource(
|
||||||
`${runtimeTemplate.supportsConst() ? "const" : "var"} ${
|
`${runtimeTemplate.renderConst()} ${
|
||||||
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
||||||
} = ${content};`
|
} = ${content};`
|
||||||
);
|
);
|
||||||
|
|
|
@ -60,7 +60,7 @@ class AssetSourceGenerator extends Generator {
|
||||||
concatenationScope.registerNamespaceExport(
|
concatenationScope.registerNamespaceExport(
|
||||||
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
||||||
);
|
);
|
||||||
sourceContent = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${
|
sourceContent = `${runtimeTemplate.renderConst()} ${
|
||||||
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
||||||
} = ${JSON.stringify(encodedSource)};`;
|
} = ${JSON.stringify(encodedSource)};`;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -171,11 +171,7 @@ class CssGenerator extends Generator {
|
||||||
usedIdentifiers.add(identifier);
|
usedIdentifiers.add(identifier);
|
||||||
generateContext.concatenationScope.registerExport(name, identifier);
|
generateContext.concatenationScope.registerExport(name, identifier);
|
||||||
source.add(
|
source.add(
|
||||||
`${
|
`${generateContext.runtimeTemplate.renderConst()} ${identifier} = ${JSON.stringify(v)};\n`
|
||||||
generateContext.runtimeTemplate.supportsConst()
|
|
||||||
? "const"
|
|
||||||
: "var"
|
|
||||||
} ${identifier} = ${JSON.stringify(v)};\n`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return source;
|
return source;
|
||||||
|
|
|
@ -1234,14 +1234,9 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
|
||||||
mode.hidden
|
mode.hidden
|
||||||
)
|
)
|
||||||
: /** @type {ExportModeIgnored} */ (mode.ignored);
|
: /** @type {ExportModeIgnored} */ (mode.ignored);
|
||||||
const modern =
|
|
||||||
runtimeTemplate.supportsConst() &&
|
|
||||||
runtimeTemplate.supportsArrowFunction();
|
|
||||||
let content =
|
let content =
|
||||||
"/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};\n" +
|
"/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};\n" +
|
||||||
`/* harmony reexport (unknown) */ for(${
|
`/* harmony reexport (unknown) */ for(${runtimeTemplate.renderConst()} __WEBPACK_IMPORT_KEY__ in ${importVar}) `;
|
||||||
modern ? "const" : "var"
|
|
||||||
} __WEBPACK_IMPORT_KEY__ in ${importVar}) `;
|
|
||||||
|
|
||||||
// Filter out exports which are defined by other exports
|
// Filter out exports which are defined by other exports
|
||||||
// and filter out default export because it cannot be reexported with *
|
// and filter out default export because it cannot be reexported with *
|
||||||
|
@ -1256,7 +1251,7 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
|
||||||
}
|
}
|
||||||
|
|
||||||
content += "__WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = ";
|
content += "__WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = ";
|
||||||
content += modern
|
content += runtimeTemplate.supportsArrowFunction()
|
||||||
? `() => ${importVar}[__WEBPACK_IMPORT_KEY__]`
|
? `() => ${importVar}[__WEBPACK_IMPORT_KEY__]`
|
||||||
: `function(key) { return ${importVar}[key]; }.bind(0, __WEBPACK_IMPORT_KEY__)`;
|
: `function(key) { return ${importVar}[key]; }.bind(0, __WEBPACK_IMPORT_KEY__)`;
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ class JsonGenerator extends Generator {
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
let content;
|
let content;
|
||||||
if (concatenationScope) {
|
if (concatenationScope) {
|
||||||
content = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${
|
content = `${runtimeTemplate.renderConst()} ${
|
||||||
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
ConcatenationScope.NAMESPACE_OBJECT_EXPORT
|
||||||
} = ${jsonExpr};`;
|
} = ${jsonExpr};`;
|
||||||
concatenationScope.registerNamespaceExport(
|
concatenationScope.registerNamespaceExport(
|
||||||
|
|
|
@ -144,7 +144,14 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
|
||||||
renderStartup(
|
renderStartup(
|
||||||
source,
|
source,
|
||||||
module,
|
module,
|
||||||
{ moduleGraph, chunk, codeGenerationResults, inlined, inlinedInIIFE },
|
{
|
||||||
|
moduleGraph,
|
||||||
|
chunk,
|
||||||
|
codeGenerationResults,
|
||||||
|
inlined,
|
||||||
|
inlinedInIIFE,
|
||||||
|
runtimeTemplate
|
||||||
|
},
|
||||||
{ options, compilation }
|
{ options, compilation }
|
||||||
) {
|
) {
|
||||||
const result = new ConcatSource(source);
|
const result = new ConcatSource(source);
|
||||||
|
@ -177,10 +184,6 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const varType = compilation.outputOptions.environment.const
|
|
||||||
? "const"
|
|
||||||
: "var";
|
|
||||||
|
|
||||||
outer: for (const exportInfo of exportsInfo) {
|
outer: for (const exportInfo of exportsInfo) {
|
||||||
if (!exportInfo.provided) continue;
|
if (!exportInfo.provided) continue;
|
||||||
|
|
||||||
|
@ -217,9 +220,9 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
|
||||||
} else {
|
} else {
|
||||||
finalName = `${RuntimeGlobals.exports}${Template.toIdentifier(originalName)}`;
|
finalName = `${RuntimeGlobals.exports}${Template.toIdentifier(originalName)}`;
|
||||||
result.add(
|
result.add(
|
||||||
`${varType} ${finalName} = ${RuntimeGlobals.exports}${propertyAccess([
|
`${runtimeTemplate.renderConst()} ${finalName} = ${RuntimeGlobals.exports}${propertyAccess(
|
||||||
usedName
|
[usedName]
|
||||||
])};\n`
|
)};\n`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +240,9 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
|
||||||
|
|
||||||
if (topLevelDeclarations && topLevelDeclarations.has(originalName)) {
|
if (topLevelDeclarations && topLevelDeclarations.has(originalName)) {
|
||||||
const name = `${RuntimeGlobals.exports}${Template.toIdentifier(originalName)}`;
|
const name = `${RuntimeGlobals.exports}${Template.toIdentifier(originalName)}`;
|
||||||
result.add(`${varType} ${name} = ${finalName};\n`);
|
result.add(
|
||||||
|
`${runtimeTemplate.renderConst()} ${name} = ${finalName};\n`
|
||||||
|
);
|
||||||
shortHandedExports.push(`${name} as ${originalName}`);
|
shortHandedExports.push(`${name} as ${originalName}`);
|
||||||
} else {
|
} else {
|
||||||
exports.push([originalName, finalName]);
|
exports.push([originalName, finalName]);
|
||||||
|
@ -263,7 +268,9 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [exportName, final] of exports) {
|
for (const [exportName, final] of exports) {
|
||||||
result.add(`export ${varType} ${exportName} = ${final};\n`);
|
result.add(
|
||||||
|
`export ${runtimeTemplate.renderConst()} ${exportName} = ${final};\n`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -3,9 +3,10 @@ const path = require("path");
|
||||||
|
|
||||||
it("module-import should correctly get fallback type", function() {
|
it("module-import should correctly get fallback type", function() {
|
||||||
const content = fs.readFileSync(path.resolve(__dirname, "a.js"), "utf-8");
|
const content = fs.readFileSync(path.resolve(__dirname, "a.js"), "utf-8");
|
||||||
expect(content).toContain(`import { default as __WEBPACK_EXTERNAL_MODULE_external0_default__ } from "external0"`); // module
|
expect(content).toContain(`import { default as __WEBPACK_EXTERNAL_MODULE_external0_default__ } from "external0";`); // module
|
||||||
|
expect(content).toContain(`const __WEBPACK_EXTERNAL_createRequire_require = __WEBPACK_EXTERNAL_createRequire(import.meta.url);`); // module
|
||||||
expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external1__ from "external1"`); // module
|
expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external1__ from "external1"`); // module
|
||||||
expect(content).toContain(`module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("external2")`); // node-commonjs
|
expect(content).toContain(`module.exports = __WEBPACK_EXTERNAL_createRequire_require("external2")`); // node-commonjs
|
||||||
expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external3__ from "external3"`); // module
|
expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external3__ from "external3"`); // module
|
||||||
expect(content).toContain(`const external3_2 = Promise.resolve(/*! import() */).then`); // import
|
expect(content).toContain(`const external3_2 = Promise.resolve(/*! import() */).then`); // import
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
const pathModule = __non_webpack_require__('path');
|
||||||
|
|
||||||
|
export default pathModule;
|
|
@ -0,0 +1,5 @@
|
||||||
|
import pathModule from "./common.js";
|
||||||
|
|
||||||
|
it("should work", () => {
|
||||||
|
expect(typeof pathModule.dirname).toBe("function");
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const supportsRequireInModule = require("../../../helpers/supportsRequireInModule");
|
||||||
|
|
||||||
|
module.exports = () => supportsRequireInModule();
|
|
@ -0,0 +1,10 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/** @type {import("../../../../").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
devtool: "eval-source-map",
|
||||||
|
target: "node",
|
||||||
|
experiments: {
|
||||||
|
outputModule: true
|
||||||
|
}
|
||||||
|
};
|
|
@ -5356,6 +5356,9 @@ declare class ExternalModule extends Module {
|
||||||
normalModuleFactory: NormalModuleFactory
|
normalModuleFactory: NormalModuleFactory
|
||||||
): void;
|
): void;
|
||||||
static ModuleExternalInitFragment: typeof ModuleExternalInitFragment;
|
static ModuleExternalInitFragment: typeof ModuleExternalInitFragment;
|
||||||
|
static getExternalModuleNodeCommonjsInitFragment: (
|
||||||
|
runtimeTemplate: RuntimeTemplate
|
||||||
|
) => InitFragment<ChunkRenderContextJavascriptModulesPlugin>;
|
||||||
}
|
}
|
||||||
declare interface ExternalModuleInfo {
|
declare interface ExternalModuleInfo {
|
||||||
type: "external";
|
type: "external";
|
||||||
|
@ -15545,6 +15548,7 @@ declare abstract class RuntimeTemplate {
|
||||||
supportTemplateLiteral(): boolean;
|
supportTemplateLiteral(): boolean;
|
||||||
supportNodePrefixForCoreModules(): boolean;
|
supportNodePrefixForCoreModules(): boolean;
|
||||||
renderNodePrefixForCoreModule(mod: string): string;
|
renderNodePrefixForCoreModule(mod: string): string;
|
||||||
|
renderConst(): "var" | "const";
|
||||||
returningFunction(returnValue: string, args?: string): string;
|
returningFunction(returnValue: string, args?: string): string;
|
||||||
basicFunction(args: string, body: string | string[]): string;
|
basicFunction(args: string, body: string | string[]): string;
|
||||||
concatenation(...args: (string | { expr: string })[]): string;
|
concatenation(...args: (string | { expr: string })[]): string;
|
||||||
|
|
Loading…
Reference in New Issue