diff --git a/lib/ExternalModule.js b/lib/ExternalModule.js index cf22c0ca5..79a8d8637 100644 --- a/lib/ExternalModule.js +++ b/lib/ExternalModule.js @@ -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,6 +578,25 @@ class ExternalModule extends Module { canMangle = true; } break; + case "module": + if (this.buildInfo.module) { + if (!Array.isArray(request) || request.length === 1) { + this.buildMeta.exportsType = "namespace"; + canMangle = true; + } + } else { + this.buildMeta.async = true; + EnvironmentNotSupportAsyncWarning.check( + this, + compilation.runtimeTemplate, + "external module" + ); + if (!Array.isArray(request) || request.length === 1) { + this.buildMeta.exportsType = "namespace"; + canMangle = false; + } + } + break; case "script": this.buildMeta.async = true; EnvironmentNotSupportAsyncWarning.check( @@ -613,45 +613,18 @@ class ExternalModule extends Module { "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"; - canMangle = true; - } - } else { - this.buildMeta.async = true; - EnvironmentNotSupportAsyncWarning.check( - this, - compilation.runtimeTemplate, - "external module" - ); - if (!Array.isArray(request) || request.length === 1) { - this.buildMeta.exportsType = "namespace"; - canMangle = false; - } - } + this.buildMeta.async = true; + EnvironmentNotSupportAsyncWarning.check( + this, + compilation.runtimeTemplate, + "external import" + ); + if (!Array.isArray(request) || request.length === 1) { + this.buildMeta.exportsType = "namespace"; + canMangle = false; } - - if (type === "import") { - this.buildMeta.async = true; - EnvironmentNotSupportAsyncWarning.check( - this, - compilation.runtimeTemplate, - "external import" - ); - if (!Array.isArray(request) || request.length === 1) { - 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,52 +744,43 @@ class ExternalModule extends Module { runtimeTemplate ); } + case "import": + return getSourceForImportExternal( + request, + runtimeTemplate, + /** @type {ImportDependencyMeta} */ (dependencyMeta) + ); case "script": return getSourceForScriptExternal(request, runtimeTemplate); - case "module": - case "import": - case "module-import": { - const type = this.getModuleImportType(externalType); - if (type === "import") { + case "module": { + if (!(/** @type {BuildInfo} */ (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, /** @type {ImportDependencyMeta} */ (dependencyMeta) ); } - - if (type === "module") { - if (!(/** @type {BuildInfo} */ (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, - /** @type {ImportDependencyMeta} */ (dependencyMeta) - ); - } - if (!runtimeTemplate.supportsEcmaScriptModuleSyntax()) { - throw new Error( - "The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module'" - ); - } - return getSourceForModuleExternal( - request, - moduleGraph.getExportsInfo(this), - runtime, - runtimeTemplate, - /** @type {ImportDependencyMeta} */ (dependencyMeta) + if (!runtimeTemplate.supportsEcmaScriptModuleSyntax()) { + throw new Error( + "The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module'" ); } - - break; + return getSourceForModuleExternal( + request, + moduleGraph.getExportsInfo(this), + runtime, + runtimeTemplate, + /** @type {ImportDependencyMeta} */ (dependencyMeta) + ); } case "var": case "promise": @@ -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 )}` ); diff --git a/test/configCases/externals/module-import/a.js b/test/configCases/externals/module-import/a.js index 97b356b1b..d923fc87a 100644 --- a/test/configCases/externals/module-import/a.js +++ b/test/configCases/externals/module-import/a.js @@ -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); diff --git a/test/configCases/externals/module-import/index.js b/test/configCases/externals/module-import/index.js index 4036fafe9..af64c4613 100644 --- a/test/configCases/externals/module-import/index.js +++ b/test/configCases/externals/module-import/index.js @@ -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 }); diff --git a/types.d.ts b/types.d.ts index 83639a045..caa519ac7 100644 --- a/types.d.ts +++ b/types.d.ts @@ -4582,7 +4582,6 @@ declare class ExternalModule extends Module { externalType: string; userRequest: string; dependencyMeta?: ImportDependencyMeta | CssImportDependencyMeta; - getModuleImportType(externalType: string): string; /** * restore unsafe cache data