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

View File

@ -1,6 +1,7 @@
import external0 from "external0"; // module import external0 from "external0"; // module
const external1 = require("external1"); // module const external1 = require("external1"); // module
const external2 = require("external2"); // node-commonjs 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() { 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 * as __WEBPACK_EXTERNAL_MODULE_external0__ from "external0";`); // module 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(`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(import.meta.url)("external2")`); // node-commonjs
expect(content).toContain(`module.exports = import("external3");`); // import 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; externalType: string;
userRequest: string; userRequest: string;
dependencyMeta?: ImportDependencyMeta | CssImportDependencyMeta; dependencyMeta?: ImportDependencyMeta | CssImportDependencyMeta;
getModuleImportType(externalType: string): string;
/** /**
* restore unsafe cache data * restore unsafe cache data