Skip to content

Commit c1a0a46

Browse files
committed
fix(externals): distinguish “module” and “import” in “module-import”
1 parent dae16ad commit c1a0a46

File tree

4 files changed

+87
-100
lines changed

4 files changed

+87
-100
lines changed

lib/ExternalModule.js

Lines changed: 79 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ class ExternalModule extends Module {
526526
* @returns {string} a unique identifier of the module
527527
*/
528528
identifier() {
529-
return `external ${this.externalType} ${JSON.stringify(this.request)}`;
529+
return `external ${this._resolveExternalType(this.externalType)} ${JSON.stringify(this.request)}`;
530530
}
531531

532532
/**
@@ -546,25 +546,6 @@ class ExternalModule extends Module {
546546
return callback(null, !this.buildMeta);
547547
}
548548

549-
/**
550-
* @param {string} externalType raw external type
551-
* @returns {string} resolved external type
552-
*/
553-
getModuleImportType(externalType) {
554-
if (externalType === "module-import") {
555-
if (
556-
this.dependencyMeta &&
557-
/** @type {ImportDependencyMeta} */ (this.dependencyMeta).externalType
558-
) {
559-
return /** @type {ImportDependencyMeta} */ (this.dependencyMeta)
560-
.externalType;
561-
}
562-
return "module";
563-
}
564-
565-
return externalType;
566-
}
567-
568549
/**
569550
* @param {WebpackOptions} options webpack options
570551
* @param {Compilation} compilation the compilation
@@ -597,6 +578,25 @@ class ExternalModule extends Module {
597578
canMangle = true;
598579
}
599580
break;
581+
case "module":
582+
if (this.buildInfo.module) {
583+
if (!Array.isArray(request) || request.length === 1) {
584+
this.buildMeta.exportsType = "namespace";
585+
canMangle = true;
586+
}
587+
} else {
588+
this.buildMeta.async = true;
589+
EnvironmentNotSupportAsyncWarning.check(
590+
this,
591+
compilation.runtimeTemplate,
592+
"external module"
593+
);
594+
if (!Array.isArray(request) || request.length === 1) {
595+
this.buildMeta.exportsType = "namespace";
596+
canMangle = false;
597+
}
598+
}
599+
break;
600600
case "script":
601601
this.buildMeta.async = true;
602602
EnvironmentNotSupportAsyncWarning.check(
@@ -613,45 +613,18 @@ class ExternalModule extends Module {
613613
"external promise"
614614
);
615615
break;
616-
case "module":
617616
case "import":
618-
case "module-import": {
619-
const type = this.getModuleImportType(externalType);
620-
if (type === "module") {
621-
if (this.buildInfo.module) {
622-
if (!Array.isArray(request) || request.length === 1) {
623-
this.buildMeta.exportsType = "namespace";
624-
canMangle = true;
625-
}
626-
} else {
627-
this.buildMeta.async = true;
628-
EnvironmentNotSupportAsyncWarning.check(
629-
this,
630-
compilation.runtimeTemplate,
631-
"external module"
632-
);
633-
if (!Array.isArray(request) || request.length === 1) {
634-
this.buildMeta.exportsType = "namespace";
635-
canMangle = false;
636-
}
637-
}
638-
}
639-
640-
if (type === "import") {
641-
this.buildMeta.async = true;
642-
EnvironmentNotSupportAsyncWarning.check(
643-
this,
644-
compilation.runtimeTemplate,
645-
"external import"
646-
);
647-
if (!Array.isArray(request) || request.length === 1) {
648-
this.buildMeta.exportsType = "namespace";
649-
canMangle = false;
650-
}
617+
this.buildMeta.async = true;
618+
EnvironmentNotSupportAsyncWarning.check(
619+
this,
620+
compilation.runtimeTemplate,
621+
"external import"
622+
);
623+
if (!Array.isArray(request) || request.length === 1) {
624+
this.buildMeta.exportsType = "namespace";
625+
canMangle = false;
651626
}
652-
653627
break;
654-
}
655628
}
656629
this.addDependency(new StaticExportsDependency(true, canMangle));
657630
callback();
@@ -687,9 +660,31 @@ class ExternalModule extends Module {
687660
let { request, externalType } = this;
688661
if (typeof request === "object" && !Array.isArray(request))
689662
request = request[externalType];
663+
externalType = this._resolveExternalType(externalType);
690664
return { request, externalType };
691665
}
692666

667+
/**
668+
* Resolve the detailed external type from the raw external type.
669+
* e.g. resolve "module" or "import" from "module-import" type
670+
* @param {string} externalType raw external type
671+
* @returns {string} resolved external type
672+
*/
673+
_resolveExternalType(externalType) {
674+
if (externalType === "module-import") {
675+
if (
676+
this.dependencyMeta &&
677+
/** @type {ImportDependencyMeta} */ (this.dependencyMeta).externalType
678+
) {
679+
return /** @type {ImportDependencyMeta} */ (this.dependencyMeta)
680+
.externalType;
681+
}
682+
return "module";
683+
}
684+
685+
return externalType;
686+
}
687+
693688
/**
694689
* @private
695690
* @param {string | string[]} request request
@@ -749,52 +744,43 @@ class ExternalModule extends Module {
749744
runtimeTemplate
750745
);
751746
}
747+
case "import":
748+
return getSourceForImportExternal(
749+
request,
750+
runtimeTemplate,
751+
/** @type {ImportDependencyMeta} */ (dependencyMeta)
752+
);
752753
case "script":
753754
return getSourceForScriptExternal(request, runtimeTemplate);
754-
case "module":
755-
case "import":
756-
case "module-import": {
757-
const type = this.getModuleImportType(externalType);
758-
if (type === "import") {
759-
return getSourceForImportExternal(
760-
request,
761-
runtimeTemplate,
762-
/** @type {ImportDependencyMeta} */ (dependencyMeta)
763-
);
764-
}
765-
766-
if (type === "module") {
767-
if (!(/** @type {BuildInfo} */ (this.buildInfo).module)) {
768-
if (!runtimeTemplate.supportsDynamicImport()) {
769-
throw new Error(
770-
`The target environment doesn't support dynamic import() syntax so it's not possible to use external type 'module' within a script${
771-
runtimeTemplate.supportsEcmaScriptModuleSyntax()
772-
? "\nDid you mean to build a EcmaScript Module ('output.module: true')?"
773-
: ""
774-
}`
775-
);
776-
}
777-
return getSourceForImportExternal(
778-
request,
779-
runtimeTemplate,
780-
/** @type {ImportDependencyMeta} */ (dependencyMeta)
781-
);
782-
}
783-
if (!runtimeTemplate.supportsEcmaScriptModuleSyntax()) {
755+
case "module": {
756+
if (!(/** @type {BuildInfo} */ (this.buildInfo).module)) {
757+
if (!runtimeTemplate.supportsDynamicImport()) {
784758
throw new Error(
785-
"The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module'"
759+
`The target environment doesn't support dynamic import() syntax so it's not possible to use external type 'module' within a script${
760+
runtimeTemplate.supportsEcmaScriptModuleSyntax()
761+
? "\nDid you mean to build a EcmaScript Module ('output.module: true')?"
762+
: ""
763+
}`
786764
);
787765
}
788-
return getSourceForModuleExternal(
766+
return getSourceForImportExternal(
789767
request,
790-
moduleGraph.getExportsInfo(this),
791-
runtime,
792768
runtimeTemplate,
793769
/** @type {ImportDependencyMeta} */ (dependencyMeta)
794770
);
795771
}
796-
797-
break;
772+
if (!runtimeTemplate.supportsEcmaScriptModuleSyntax()) {
773+
throw new Error(
774+
"The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module'"
775+
);
776+
}
777+
return getSourceForModuleExternal(
778+
request,
779+
moduleGraph.getExportsInfo(this),
780+
runtime,
781+
runtimeTemplate,
782+
/** @type {ImportDependencyMeta} */ (dependencyMeta)
783+
);
798784
}
799785
case "var":
800786
case "promise":
@@ -939,7 +925,7 @@ class ExternalModule extends Module {
939925
updateHash(hash, context) {
940926
const { chunkGraph } = context;
941927
hash.update(
942-
`${this.externalType}${JSON.stringify(this.request)}${this.isOptional(
928+
`${this._resolveExternalType(this.externalType)}${JSON.stringify(this.request)}${this.isOptional(
943929
chunkGraph.moduleGraph
944930
)}`
945931
);
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import external0 from "external0"; // module
22
const external1 = require("external1"); // module
33
const external2 = require("external2"); // node-commonjs
4-
const external3 = import("external3"); // import
4+
import external3_1 from "external3"; // module
5+
const external3_2 = import("external3"); // import
56

6-
console.log(external0, external1, external2, external3);
7+
console.log(external0, external1, external3_1, external3_2);

test/configCases/externals/module-import/index.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ const path = require("path");
33

44
it("module-import should correctly get fallback type", function() {
55
const content = fs.readFileSync(path.resolve(__dirname, "a.js"), "utf-8");
6-
expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external0__ from "external0";`); // module
7-
expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external1__ from "external1";`); // module
8-
expect(content).toContain(`module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("external2");`); // node-commonjs
9-
expect(content).toContain(`module.exports = import("external3");`); // import
6+
expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external0__ from "external0"`); // module
7+
expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external1__ from "external1"`); // module
8+
expect(content).toContain(`module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("external2")`); // node-commonjs
9+
expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external3__ from "external3"`); // module
10+
expect(content).toContain(`const external3_2 = Promise.resolve(/*! import() */).then`); // import
1011
});

types.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4582,7 +4582,6 @@ declare class ExternalModule extends Module {
45824582
externalType: string;
45834583
userRequest: string;
45844584
dependencyMeta?: ImportDependencyMeta | CssImportDependencyMeta;
4585-
getModuleImportType(externalType: string): string;
45864585

45874586
/**
45884587
* restore unsafe cache data

0 commit comments

Comments
 (0)