add `node-commonjs` external type to use `createRequire` for commonjs externals

for `module` externals, fallback to `import()` when not in module mode
This commit is contained in:
Tobias Koppers 2021-06-25 11:22:55 +02:00
parent a53578be7e
commit a1f0d23dcc
4 changed files with 61 additions and 13 deletions

View File

@ -94,6 +94,36 @@ const getSourceForCommonJsExternal = moduleAndSpecifiers => {
};
};
/**
* @param {string|string[]} moduleAndSpecifiers the module request
* @returns {SourceData} the generated source
*/
const getSourceForCommonJsExternalInNodeModule = moduleAndSpecifiers => {
const chunkInitFragments = [
new InitFragment(
'import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "module";\n',
InitFragment.STAGE_HARMONY_IMPORTS,
0,
"external module node-commonjs"
)
];
if (!Array.isArray(moduleAndSpecifiers)) {
return {
expression: `__WEBPACK_EXTERNAL_createRequire(import.meta.url)(${JSON.stringify(
moduleAndSpecifiers
)})`,
chunkInitFragments
};
}
const moduleName = moduleAndSpecifiers[0];
return {
expression: `__WEBPACK_EXTERNAL_createRequire(import.meta.url)(${JSON.stringify(
moduleName
)})${propertyAccess(moduleAndSpecifiers, 1)}`,
chunkInitFragments
};
};
/**
* @param {string|string[]} moduleAndSpecifiers the module request
* @param {RuntimeTemplate} runtimeTemplate the runtime template
@ -400,9 +430,17 @@ class ExternalModule extends Module {
break;
case "system":
case "module":
if (!Array.isArray(request) || request.length === 1) {
this.buildMeta.exportsType = "namespace";
canMangle = true;
if (this.buildInfo.module) {
if (!Array.isArray(request) || request.length === 1) {
this.buildMeta.exportsType = "namespace";
canMangle = true;
}
} else {
this.buildMeta.async = true;
if (!Array.isArray(request) || request.length === 1) {
this.buildMeta.exportsType = "namespace";
canMangle = false;
}
}
break;
case "script":
@ -440,11 +478,6 @@ class ExternalModule extends Module {
_getRequestAndExternalType() {
let { request, externalType } = this;
let match;
if ((match = /^([^/]+)\/([^/]+)$/.exec(externalType))) {
// TODO add chunk specific code generation, and get that from the chunk format
externalType = this.buildInfo.module ? match[2] : match[1];
}
if (typeof request === "object" && !Array.isArray(request))
request = request[externalType];
return { request, externalType };
@ -466,6 +499,10 @@ class ExternalModule extends Module {
case "commonjs2":
case "commonjs-module":
return getSourceForCommonJsExternal(request);
case "node-commonjs":
return this.buildInfo.module
? getSourceForCommonJsExternalInNodeModule(request)
: getSourceForCommonJsExternal(request);
case "amd":
case "amd-require":
case "umd":
@ -483,6 +520,17 @@ class ExternalModule extends Module {
case "script":
return getSourceForScriptExternal(request, runtimeTemplate);
case "module":
if (!this.buildInfo.module) {
if (!runtimeTemplate.supportsDynamicImport()) {
throw new Error(
"The target environment doesn't support dynamic import() syntax so it's not possible to use external type 'module' within a script" +
(runtimeTemplate.supportsEcmaScriptModuleSyntax()
? "\nDid you mean to build a EcmaScript Module ('output.module: true')?"
: "")
);
}
return getSourceForImportExternal(request, runtimeTemplate);
}
if (!runtimeTemplate.supportsEcmaScriptModuleSyntax()) {
throw new Error(
"The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module'"

View File

@ -113,7 +113,7 @@ class WebpackOptionsApply extends OptionsApply {
if (options.externalsPresets.nwjs) {
//@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
const ExternalsPlugin = require("./ExternalsPlugin");
new ExternalsPlugin("commonjs/module", "nw.gui").apply(compiler);
new ExternalsPlugin("node-commonjs", "nw.gui").apply(compiler);
}
if (options.externalsPresets.webAsync) {
//@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697

View File

@ -22,7 +22,7 @@ class ElectronTargetPlugin {
* @returns {void}
*/
apply(compiler) {
new ExternalsPlugin("commonjs/module", [
new ExternalsPlugin("node-commonjs", [
"clipboard",
"crash-reporter",
"electron",
@ -34,7 +34,7 @@ class ElectronTargetPlugin {
]).apply(compiler);
switch (this._context) {
case "main":
new ExternalsPlugin("commonjs/module", [
new ExternalsPlugin("node-commonjs", [
"app",
"auto-updater",
"browser-window",
@ -54,7 +54,7 @@ class ElectronTargetPlugin {
break;
case "preload":
case "renderer":
new ExternalsPlugin("commonjs/module", [
new ExternalsPlugin("node-commonjs", [
"desktop-capturer",
"ipc-renderer",
"remote",

View File

@ -69,7 +69,7 @@ class NodeTargetPlugin {
* @returns {void}
*/
apply(compiler) {
new ExternalsPlugin("commonjs/module", builtins).apply(compiler);
new ExternalsPlugin("node-commonjs", builtins).apply(compiler);
}
}