fix(externals): distinguish “module” and “import” in “module-import”

This commit is contained in:
fi3ework 2024-09-24 23:47:27 +08:00
parent dae16ad11e
commit c1a0a4666e
4 changed files with 87 additions and 100 deletions

View File

@ -526,7 +526,7 @@ class ExternalModule extends Module {
* @returns {string} a unique identifier of the module
*/
identifier() {
return `external ${this.externalType} ${JSON.stringify(this.request)}`;
return `external ${this._resolveExternalType(this.externalType)} ${JSON.stringify(this.request)}`;
}
/**
@ -546,25 +546,6 @@ class ExternalModule extends Module {
return callback(null, !this.buildMeta);
}
/**
* @param {string} externalType raw external type
* @returns {string} resolved external type
*/
getModuleImportType(externalType) {
if (externalType === "module-import") {
if (
this.dependencyMeta &&
/** @type {ImportDependencyMeta} */ (this.dependencyMeta).externalType
) {
return /** @type {ImportDependencyMeta} */ (this.dependencyMeta)
.externalType;
}
return "module";
}
return externalType;
}
/**
* @param {WebpackOptions} options webpack options
* @param {Compilation} compilation the compilation
@ -597,27 +578,7 @@ class ExternalModule extends Module {
canMangle = true;
}
break;
case "script":
this.buildMeta.async = true;
EnvironmentNotSupportAsyncWarning.check(
this,
compilation.runtimeTemplate,
"external script"
);
break;
case "promise":
this.buildMeta.async = true;
EnvironmentNotSupportAsyncWarning.check(
this,
compilation.runtimeTemplate,
"external promise"
);
break;
case "module":
case "import":
case "module-import": {
const type = this.getModuleImportType(externalType);
if (type === "module") {
if (this.buildInfo.module) {
if (!Array.isArray(request) || request.length === 1) {
this.buildMeta.exportsType = "namespace";
@ -635,9 +596,24 @@ class ExternalModule extends Module {
canMangle = false;
}
}
}
if (type === "import") {
break;
case "script":
this.buildMeta.async = true;
EnvironmentNotSupportAsyncWarning.check(
this,
compilation.runtimeTemplate,
"external script"
);
break;
case "promise":
this.buildMeta.async = true;
EnvironmentNotSupportAsyncWarning.check(
this,
compilation.runtimeTemplate,
"external promise"
);
break;
case "import":
this.buildMeta.async = true;
EnvironmentNotSupportAsyncWarning.check(
this,
@ -648,11 +624,8 @@ class ExternalModule extends Module {
this.buildMeta.exportsType = "namespace";
canMangle = false;
}
}
break;
}
}
this.addDependency(new StaticExportsDependency(true, canMangle));
callback();
}
@ -687,9 +660,31 @@ class ExternalModule extends Module {
let { request, externalType } = this;
if (typeof request === "object" && !Array.isArray(request))
request = request[externalType];
externalType = this._resolveExternalType(externalType);
return { request, externalType };
}
/**
* Resolve the detailed external type from the raw external type.
* e.g. resolve "module" or "import" from "module-import" type
* @param {string} externalType raw external type
* @returns {string} resolved external type
*/
_resolveExternalType(externalType) {
if (externalType === "module-import") {
if (
this.dependencyMeta &&
/** @type {ImportDependencyMeta} */ (this.dependencyMeta).externalType
) {
return /** @type {ImportDependencyMeta} */ (this.dependencyMeta)
.externalType;
}
return "module";
}
return externalType;
}
/**
* @private
* @param {string | string[]} request request
@ -749,21 +744,15 @@ class ExternalModule extends Module {
runtimeTemplate
);
}
case "script":
return getSourceForScriptExternal(request, runtimeTemplate);
case "module":
case "import":
case "module-import": {
const type = this.getModuleImportType(externalType);
if (type === "import") {
return getSourceForImportExternal(
request,
runtimeTemplate,
/** @type {ImportDependencyMeta} */ (dependencyMeta)
);
}
if (type === "module") {
case "script":
return getSourceForScriptExternal(request, runtimeTemplate);
case "module": {
if (!(/** @type {BuildInfo} */ (this.buildInfo).module)) {
if (!runtimeTemplate.supportsDynamicImport()) {
throw new Error(
@ -793,9 +782,6 @@ class ExternalModule extends Module {
/** @type {ImportDependencyMeta} */ (dependencyMeta)
);
}
break;
}
case "var":
case "promise":
case "const":
@ -939,7 +925,7 @@ class ExternalModule extends Module {
updateHash(hash, context) {
const { chunkGraph } = context;
hash.update(
`${this.externalType}${JSON.stringify(this.request)}${this.isOptional(
`${this._resolveExternalType(this.externalType)}${JSON.stringify(this.request)}${this.isOptional(
chunkGraph.moduleGraph
)}`
);

View File

@ -1,6 +1,7 @@
import external0 from "external0"; // module
const external1 = require("external1"); // module
const external2 = require("external2"); // node-commonjs
const external3 = import("external3"); // import
import external3_1 from "external3"; // module
const external3_2 = import("external3"); // import
console.log(external0, external1, external2, external3);
console.log(external0, external1, external3_1, external3_2);

View File

@ -3,8 +3,9 @@ const path = require("path");
it("module-import should correctly get fallback type", function() {
const content = fs.readFileSync(path.resolve(__dirname, "a.js"), "utf-8");
expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external0__ from "external0";`); // 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 = import("external3");`); // import
expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external0__ from "external0"`); // 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(`import * as __WEBPACK_EXTERNAL_MODULE_external3__ from "external3"`); // module
expect(content).toContain(`const external3_2 = Promise.resolve(/*! import() */).then`); // import
});

1
types.d.ts vendored
View File

@ -4582,7 +4582,6 @@ declare class ExternalModule extends Module {
externalType: string;
userRequest: string;
dependencyMeta?: ImportDependencyMeta | CssImportDependencyMeta;
getModuleImportType(externalType: string): string;
/**
* restore unsafe cache data