123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
- "use strict";
- const { OriginalSource, RawSource } = require("webpack-sources");
- const ConcatenationScope = require("./ConcatenationScope");
- const EnvironmentNotSupportAsyncWarning = require("./EnvironmentNotSupportAsyncWarning");
- const { UsageState } = require("./ExportsInfo");
- const InitFragment = require("./InitFragment");
- const Module = require("./Module");
- const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants");
- const RuntimeGlobals = require("./RuntimeGlobals");
- const Template = require("./Template");
- const StaticExportsDependency = require("./dependencies/StaticExportsDependency");
- const createHash = require("./util/createHash");
- const extractUrlAndGlobal = require("./util/extractUrlAndGlobal");
- const makeSerializable = require("./util/makeSerializable");
- const propertyAccess = require("./util/propertyAccess");
- const { register } = require("./util/serialization");
- /** @typedef {import("webpack-sources").Source} Source */
- /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
- /** @typedef {import("./Chunk")} Chunk */
- /** @typedef {import("./ChunkGraph")} ChunkGraph */
- /** @typedef {import("./Compilation")} Compilation */
- /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
- /** @typedef {import("./DependencyTemplates")} DependencyTemplates */
- /** @typedef {import("./ExportsInfo")} ExportsInfo */
- /** @typedef {import("./Generator").GenerateContext} GenerateContext */
- /** @typedef {import("./Module").BuildInfo} BuildInfo */
- /** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
- /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
- /** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
- /** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
- /** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
- /** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
- /** @typedef {import("./Module").SourceTypes} SourceTypes */
- /** @typedef {import("./ModuleGraph")} ModuleGraph */
- /** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
- /** @typedef {import("./RequestShortener")} RequestShortener */
- /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
- /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
- /** @typedef {import("./WebpackError")} WebpackError */
- /** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
- /** @typedef {import("./javascript/JavascriptParser").ImportAttributes} ImportAttributes */
- /** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
- /** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
- /** @typedef {import("./util/Hash")} Hash */
- /** @typedef {typeof import("./util/Hash")} HashConstructor */
- /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
- /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
- /** @typedef {{ attributes?: ImportAttributes }} ImportDependencyMeta */
- /** @typedef {{ layer?: string, supports?: string, media?: string }} CssImportDependencyMeta */
- /** @typedef {ImportDependencyMeta | CssImportDependencyMeta} DependencyMeta */
- /**
- * @typedef {object} SourceData
- * @property {boolean=} iife
- * @property {string=} init
- * @property {string} expression
- * @property {InitFragment<ChunkRenderContext>[]=} chunkInitFragments
- * @property {ReadOnlyRuntimeRequirements=} runtimeRequirements
- */
- const TYPES = new Set(["javascript"]);
- const CSS_TYPES = new Set(["css-import"]);
- const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
- const RUNTIME_REQUIREMENTS_FOR_SCRIPT = new Set([RuntimeGlobals.loadScript]);
- const RUNTIME_REQUIREMENTS_FOR_MODULE = new Set([
- RuntimeGlobals.definePropertyGetters
- ]);
- const EMPTY_RUNTIME_REQUIREMENTS = new Set([]);
- /**
- * @param {string|string[]} variableName the variable name or path
- * @param {string} type the module system
- * @returns {SourceData} the generated source
- */
- const getSourceForGlobalVariableExternal = (variableName, type) => {
- if (!Array.isArray(variableName)) {
- // make it an array as the look up works the same basically
- variableName = [variableName];
- }
- // needed for e.g. window["some"]["thing"]
- const objectLookup = variableName.map(r => `[${JSON.stringify(r)}]`).join("");
- return {
- iife: type === "this",
- expression: `${type}${objectLookup}`
- };
- };
- /**
- * @param {string|string[]} moduleAndSpecifiers the module request
- * @returns {SourceData} the generated source
- */
- const getSourceForCommonJsExternal = moduleAndSpecifiers => {
- if (!Array.isArray(moduleAndSpecifiers)) {
- return {
- expression: `require(${JSON.stringify(moduleAndSpecifiers)})`
- };
- }
- const moduleName = moduleAndSpecifiers[0];
- return {
- expression: `require(${JSON.stringify(moduleName)})${propertyAccess(
- moduleAndSpecifiers,
- 1
- )}`
- };
- };
- /**
- * @param {string|string[]} moduleAndSpecifiers the module request
- * @param {string} importMetaName import.meta name
- * @param {boolean} needPrefix need to use `node:` prefix for `module` import
- * @returns {SourceData} the generated source
- */
- const getSourceForCommonJsExternalInNodeModule = (
- moduleAndSpecifiers,
- importMetaName,
- needPrefix
- ) => {
- const chunkInitFragments = [
- new InitFragment(
- `import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "${
- needPrefix ? "node:" : ""
- }module";\n`,
- InitFragment.STAGE_HARMONY_IMPORTS,
- 0,
- "external module node-commonjs"
- )
- ];
- if (!Array.isArray(moduleAndSpecifiers)) {
- return {
- chunkInitFragments,
- expression: `__WEBPACK_EXTERNAL_createRequire(${importMetaName}.url)(${JSON.stringify(
- moduleAndSpecifiers
- )})`
- };
- }
- const moduleName = moduleAndSpecifiers[0];
- return {
- chunkInitFragments,
- expression: `__WEBPACK_EXTERNAL_createRequire(${importMetaName}.url)(${JSON.stringify(
- moduleName
- )})${propertyAccess(moduleAndSpecifiers, 1)}`
- };
- };
- /**
- * @param {string|string[]} moduleAndSpecifiers the module request
- * @param {RuntimeTemplate} runtimeTemplate the runtime template
- * @param {ImportDependencyMeta=} dependencyMeta the dependency meta
- * @returns {SourceData} the generated source
- */
- const getSourceForImportExternal = (
- moduleAndSpecifiers,
- runtimeTemplate,
- dependencyMeta
- ) => {
- const importName = runtimeTemplate.outputOptions.importFunctionName;
- if (!runtimeTemplate.supportsDynamicImport() && importName === "import") {
- throw new Error(
- "The target environment doesn't support 'import()' so it's not possible to use external type 'import'"
- );
- }
- const attributes =
- dependencyMeta && dependencyMeta.attributes
- ? dependencyMeta.attributes._isLegacyAssert
- ? `, { assert: ${JSON.stringify(
- dependencyMeta.attributes,
- importAssertionReplacer
- )} }`
- : `, { with: ${JSON.stringify(dependencyMeta.attributes)} }`
- : "";
- if (!Array.isArray(moduleAndSpecifiers)) {
- return {
- expression: `${importName}(${JSON.stringify(
- moduleAndSpecifiers
- )}${attributes});`
- };
- }
- if (moduleAndSpecifiers.length === 1) {
- return {
- expression: `${importName}(${JSON.stringify(
- moduleAndSpecifiers[0]
- )}${attributes});`
- };
- }
- const moduleName = moduleAndSpecifiers[0];
- return {
- expression: `${importName}(${JSON.stringify(
- moduleName
- )}${attributes}).then(${runtimeTemplate.returningFunction(
- `module${propertyAccess(moduleAndSpecifiers, 1)}`,
- "module"
- )});`
- };
- };
- /**
- * @param {string} key key
- * @param {any | undefined} value value
- * @returns {undefined | string} replaced value
- */
- const importAssertionReplacer = (key, value) => {
- if (key === "_isLegacyAssert") {
- return undefined;
- }
- return value;
- };
- /**
- * @extends {InitFragment<ChunkRenderContext>}
- */
- class ModuleExternalInitFragment extends InitFragment {
- /**
- * @param {string} request import source
- * @param {string=} ident recomputed ident
- * @param {ImportDependencyMeta=} dependencyMeta the dependency meta
- * @param {string | HashConstructor=} hashFunction the hash function to use
- */
- constructor(request, ident, dependencyMeta, hashFunction = "md4") {
- if (ident === undefined) {
- ident = Template.toIdentifier(request);
- if (ident !== request) {
- ident += `_${createHash(hashFunction)
- .update(request)
- .digest("hex")
- .slice(0, 8)}`;
- }
- }
- const identifier = `__WEBPACK_EXTERNAL_MODULE_${ident}__`;
- super(
- `import * as ${identifier} from ${JSON.stringify(request)}${
- dependencyMeta && dependencyMeta.attributes
- ? dependencyMeta.attributes._isLegacyAssert
- ? ` assert ${JSON.stringify(
- dependencyMeta.attributes,
- importAssertionReplacer
- )}`
- : ` with ${JSON.stringify(dependencyMeta.attributes)}`
- : ""
- };\n`,
- InitFragment.STAGE_HARMONY_IMPORTS,
- 0,
- `external module import ${ident}`
- );
- this._ident = ident;
- this._request = request;
- this._dependencyMeta = request;
- this._identifier = identifier;
- }
- getNamespaceIdentifier() {
- return this._identifier;
- }
- }
- register(
- ModuleExternalInitFragment,
- "webpack/lib/ExternalModule",
- "ModuleExternalInitFragment",
- {
- serialize(obj, { write }) {
- write(obj._request);
- write(obj._ident);
- write(obj._dependencyMeta);
- },
- deserialize({ read }) {
- return new ModuleExternalInitFragment(read(), read(), read());
- }
- }
- );
- /**
- * @param {string} input input
- * @param {ExportsInfo} exportsInfo the exports info
- * @param {RuntimeSpec=} runtime the runtime
- * @param {RuntimeTemplate=} runtimeTemplate the runtime template
- * @returns {string | undefined} the module remapping
- */
- const generateModuleRemapping = (
- input,
- exportsInfo,
- runtime,
- runtimeTemplate
- ) => {
- if (exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused) {
- const properties = [];
- for (const exportInfo of exportsInfo.orderedExports) {
- const used = exportInfo.getUsedName(exportInfo.name, runtime);
- if (!used) continue;
- const nestedInfo = exportInfo.getNestedExportsInfo();
- if (nestedInfo) {
- const nestedExpr = generateModuleRemapping(
- `${input}${propertyAccess([exportInfo.name])}`,
- nestedInfo
- );
- if (nestedExpr) {
- properties.push(`[${JSON.stringify(used)}]: y(${nestedExpr})`);
- continue;
- }
- }
- properties.push(
- `[${JSON.stringify(used)}]: ${
- /** @type {RuntimeTemplate} */ (runtimeTemplate).returningFunction(
- `${input}${propertyAccess([exportInfo.name])}`
- )
- }`
- );
- }
- return `x({ ${properties.join(", ")} })`;
- }
- };
- /**
- * @param {string|string[]} moduleAndSpecifiers the module request
- * @param {ExportsInfo} exportsInfo exports info of this module
- * @param {RuntimeSpec} runtime the runtime
- * @param {RuntimeTemplate} runtimeTemplate the runtime template
- * @param {ImportDependencyMeta} dependencyMeta the dependency meta
- * @returns {SourceData} the generated source
- */
- const getSourceForModuleExternal = (
- moduleAndSpecifiers,
- exportsInfo,
- runtime,
- runtimeTemplate,
- dependencyMeta
- ) => {
- if (!Array.isArray(moduleAndSpecifiers))
- moduleAndSpecifiers = [moduleAndSpecifiers];
- const initFragment = new ModuleExternalInitFragment(
- moduleAndSpecifiers[0],
- undefined,
- dependencyMeta,
- runtimeTemplate.outputOptions.hashFunction
- );
- const baseAccess = `${initFragment.getNamespaceIdentifier()}${propertyAccess(
- moduleAndSpecifiers,
- 1
- )}`;
- const moduleRemapping = generateModuleRemapping(
- baseAccess,
- exportsInfo,
- runtime,
- runtimeTemplate
- );
- let expression = moduleRemapping || baseAccess;
- return {
- expression,
- init: moduleRemapping
- ? `var x = ${runtimeTemplate.basicFunction(
- "y",
- `var x = {}; ${RuntimeGlobals.definePropertyGetters}(x, y); return x`
- )} \nvar y = ${runtimeTemplate.returningFunction(
- runtimeTemplate.returningFunction("x"),
- "x"
- )}`
- : undefined,
- runtimeRequirements: moduleRemapping
- ? RUNTIME_REQUIREMENTS_FOR_MODULE
- : undefined,
- chunkInitFragments: [initFragment]
- };
- };
- /**
- * @param {string|string[]} urlAndGlobal the script request
- * @param {RuntimeTemplate} runtimeTemplate the runtime template
- * @returns {SourceData} the generated source
- */
- const getSourceForScriptExternal = (urlAndGlobal, runtimeTemplate) => {
- if (typeof urlAndGlobal === "string") {
- urlAndGlobal = extractUrlAndGlobal(urlAndGlobal);
- }
- const url = urlAndGlobal[0];
- const globalName = urlAndGlobal[1];
- return {
- init: "var __webpack_error__ = new Error();",
- expression: `new Promise(${runtimeTemplate.basicFunction(
- "resolve, reject",
- [
- `if(typeof ${globalName} !== "undefined") return resolve();`,
- `${RuntimeGlobals.loadScript}(${JSON.stringify(
- url
- )}, ${runtimeTemplate.basicFunction("event", [
- `if(typeof ${globalName} !== "undefined") return resolve();`,
- "var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
- "var realSrc = event && event.target && event.target.src;",
- "__webpack_error__.message = 'Loading script failed.\\n(' + errorType + ': ' + realSrc + ')';",
- "__webpack_error__.name = 'ScriptExternalLoadError';",
- "__webpack_error__.type = errorType;",
- "__webpack_error__.request = realSrc;",
- "reject(__webpack_error__);"
- ])}, ${JSON.stringify(globalName)});`
- ]
- )}).then(${runtimeTemplate.returningFunction(
- `${globalName}${propertyAccess(urlAndGlobal, 2)}`
- )})`,
- runtimeRequirements: RUNTIME_REQUIREMENTS_FOR_SCRIPT
- };
- };
- /**
- * @param {string} variableName the variable name to check
- * @param {string} request the request path
- * @param {RuntimeTemplate} runtimeTemplate the runtime template
- * @returns {string} the generated source
- */
- const checkExternalVariable = (variableName, request, runtimeTemplate) => {
- return `if(typeof ${variableName} === 'undefined') { ${runtimeTemplate.throwMissingModuleErrorBlock(
- { request }
- )} }\n`;
- };
- /**
- * @param {string|number} id the module id
- * @param {boolean} optional true, if the module is optional
- * @param {string|string[]} request the request path
- * @param {RuntimeTemplate} runtimeTemplate the runtime template
- * @returns {SourceData} the generated source
- */
- const getSourceForAmdOrUmdExternal = (
- id,
- optional,
- request,
- runtimeTemplate
- ) => {
- const externalVariable = `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
- `${id}`
- )}__`;
- return {
- init: optional
- ? checkExternalVariable(
- externalVariable,
- Array.isArray(request) ? request.join(".") : request,
- runtimeTemplate
- )
- : undefined,
- expression: externalVariable
- };
- };
- /**
- * @param {boolean} optional true, if the module is optional
- * @param {string|string[]} request the request path
- * @param {RuntimeTemplate} runtimeTemplate the runtime template
- * @returns {SourceData} the generated source
- */
- const getSourceForDefaultCase = (optional, request, runtimeTemplate) => {
- if (!Array.isArray(request)) {
- // make it an array as the look up works the same basically
- request = [request];
- }
- const variableName = request[0];
- const objectLookup = propertyAccess(request, 1);
- return {
- init: optional
- ? checkExternalVariable(variableName, request.join("."), runtimeTemplate)
- : undefined,
- expression: `${variableName}${objectLookup}`
- };
- };
- /** @typedef {Record<string, string | string[]>} RequestRecord */
- class ExternalModule extends Module {
- /**
- * @param {string | string[] | RequestRecord} request request
- * @param {string} type type
- * @param {string} userRequest user request
- * @param {DependencyMeta=} dependencyMeta dependency meta
- */
- constructor(request, type, userRequest, dependencyMeta) {
- super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null);
- // Info from Factory
- /** @type {string | string[] | Record<string, string | string[]>} */
- this.request = request;
- /** @type {string} */
- this.externalType = type;
- /** @type {string} */
- this.userRequest = userRequest;
- /** @type {DependencyMeta=} */
- this.dependencyMeta = dependencyMeta;
- }
- /**
- * @returns {SourceTypes} types available (do not mutate)
- */
- getSourceTypes() {
- return this.externalType === "css-import" ? CSS_TYPES : TYPES;
- }
- /**
- * @param {LibIdentOptions} options options
- * @returns {string | null} an identifier for library inclusion
- */
- libIdent(options) {
- return this.userRequest;
- }
- /**
- * @param {Chunk} chunk the chunk which condition should be checked
- * @param {Compilation} compilation the compilation
- * @returns {boolean} true, if the chunk is ok for the module
- */
- chunkCondition(chunk, { chunkGraph }) {
- return this.externalType === "css-import"
- ? true
- : chunkGraph.getNumberOfEntryModules(chunk) > 0;
- }
- /**
- * @returns {string} a unique identifier of the module
- */
- identifier() {
- return `external ${this.externalType} ${JSON.stringify(this.request)}`;
- }
- /**
- * @param {RequestShortener} requestShortener the request shortener
- * @returns {string} a user readable identifier of the module
- */
- readableIdentifier(requestShortener) {
- return "external " + JSON.stringify(this.request);
- }
- /**
- * @param {NeedBuildContext} context context info
- * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
- * @returns {void}
- */
- needBuild(context, callback) {
- return callback(null, !this.buildMeta);
- }
- /**
- * @param {WebpackOptions} options webpack options
- * @param {Compilation} compilation the compilation
- * @param {ResolverWithOptions} resolver the resolver
- * @param {InputFileSystem} fs the file system
- * @param {function(WebpackError=): void} callback callback function
- * @returns {void}
- */
- build(options, compilation, resolver, fs, callback) {
- this.buildMeta = {
- async: false,
- exportsType: undefined
- };
- this.buildInfo = {
- strict: true,
- topLevelDeclarations: new Set(),
- module: compilation.outputOptions.module
- };
- const { request, externalType } = this._getRequestAndExternalType();
- this.buildMeta.exportsType = "dynamic";
- let canMangle = false;
- this.clearDependenciesAndBlocks();
- switch (externalType) {
- case "this":
- this.buildInfo.strict = false;
- break;
- case "system":
- if (!Array.isArray(request) || request.length === 1) {
- this.buildMeta.exportsType = "namespace";
- 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(
- 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,
- 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();
- }
- /**
- * restore unsafe cache data
- * @param {object} unsafeCacheData data from getUnsafeCacheData
- * @param {NormalModuleFactory} normalModuleFactory the normal module factory handling the unsafe caching
- */
- restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory) {
- this._restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory);
- }
- /**
- * @param {ConcatenationBailoutReasonContext} context context
- * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
- */
- getConcatenationBailoutReason({ moduleGraph }) {
- switch (this.externalType) {
- case "amd":
- case "amd-require":
- case "umd":
- case "umd2":
- case "system":
- case "jsonp":
- return `${this.externalType} externals can't be concatenated`;
- }
- return undefined;
- }
- _getRequestAndExternalType() {
- let { request, externalType } = this;
- if (typeof request === "object" && !Array.isArray(request))
- request = request[externalType];
- return { request, externalType };
- }
- /**
- * @private
- * @param {string | string[]} request request
- * @param {string} externalType the external type
- * @param {RuntimeTemplate} runtimeTemplate the runtime template
- * @param {ModuleGraph} moduleGraph the module graph
- * @param {ChunkGraph} chunkGraph the chunk graph
- * @param {RuntimeSpec} runtime the runtime
- * @param {DependencyMeta | undefined} dependencyMeta the dependency meta
- * @returns {SourceData} the source data
- */
- _getSourceData(
- request,
- externalType,
- runtimeTemplate,
- moduleGraph,
- chunkGraph,
- runtime,
- dependencyMeta
- ) {
- switch (externalType) {
- case "this":
- case "window":
- case "self":
- return getSourceForGlobalVariableExternal(request, this.externalType);
- case "global":
- return getSourceForGlobalVariableExternal(
- request,
- runtimeTemplate.globalObject
- );
- case "commonjs":
- case "commonjs2":
- case "commonjs-module":
- case "commonjs-static":
- return getSourceForCommonJsExternal(request);
- case "node-commonjs":
- return /** @type {BuildInfo} */ (this.buildInfo).module
- ? getSourceForCommonJsExternalInNodeModule(
- request,
- /** @type {string} */
- (runtimeTemplate.outputOptions.importMetaName),
- runtimeTemplate.supportNodePrefixForCoreModules()
- )
- : getSourceForCommonJsExternal(request);
- case "amd":
- case "amd-require":
- case "umd":
- case "umd2":
- case "system":
- case "jsonp": {
- const id = chunkGraph.getModuleId(this);
- return getSourceForAmdOrUmdExternal(
- id !== null ? id : this.identifier(),
- this.isOptional(moduleGraph),
- request,
- runtimeTemplate
- );
- }
- case "import":
- return getSourceForImportExternal(
- request,
- runtimeTemplate,
- /** @type {ImportDependencyMeta} */ (dependencyMeta)
- );
- case "script":
- return getSourceForScriptExternal(request, runtimeTemplate);
- 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 (!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)
- );
- }
- case "var":
- case "promise":
- case "const":
- case "let":
- case "assign":
- default:
- return getSourceForDefaultCase(
- this.isOptional(moduleGraph),
- request,
- runtimeTemplate
- );
- }
- }
- /**
- * @param {CodeGenerationContext} context context for code generation
- * @returns {CodeGenerationResult} result
- */
- codeGeneration({
- runtimeTemplate,
- moduleGraph,
- chunkGraph,
- runtime,
- concatenationScope
- }) {
- const { request, externalType } = this._getRequestAndExternalType();
- switch (externalType) {
- case "asset": {
- const sources = new Map();
- sources.set(
- "javascript",
- new RawSource(`module.exports = ${JSON.stringify(request)};`)
- );
- const data = new Map();
- data.set("url", request);
- return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS, data };
- }
- case "css-import": {
- const sources = new Map();
- const dependencyMeta = /** @type {CssImportDependencyMeta} */ (
- this.dependencyMeta
- );
- const layer =
- dependencyMeta.layer !== undefined
- ? ` layer(${dependencyMeta.layer})`
- : "";
- const supports = dependencyMeta.supports
- ? ` supports(${dependencyMeta.supports})`
- : "";
- const media = dependencyMeta.media ? ` ${dependencyMeta.media}` : "";
- sources.set(
- "css-import",
- new RawSource(
- `@import url(${JSON.stringify(
- request
- )})${layer}${supports}${media};`
- )
- );
- return {
- sources,
- runtimeRequirements: EMPTY_RUNTIME_REQUIREMENTS
- };
- }
- default: {
- const sourceData = this._getSourceData(
- request,
- externalType,
- runtimeTemplate,
- moduleGraph,
- chunkGraph,
- runtime,
- this.dependencyMeta
- );
- let sourceString = sourceData.expression;
- if (sourceData.iife)
- sourceString = `(function() { return ${sourceString}; }())`;
- if (concatenationScope) {
- sourceString = `${
- runtimeTemplate.supportsConst() ? "const" : "var"
- } ${ConcatenationScope.NAMESPACE_OBJECT_EXPORT} = ${sourceString};`;
- concatenationScope.registerNamespaceExport(
- ConcatenationScope.NAMESPACE_OBJECT_EXPORT
- );
- } else {
- sourceString = `module.exports = ${sourceString};`;
- }
- if (sourceData.init)
- sourceString = `${sourceData.init}\n${sourceString}`;
- let data = undefined;
- if (sourceData.chunkInitFragments) {
- data = new Map();
- data.set("chunkInitFragments", sourceData.chunkInitFragments);
- }
- const sources = new Map();
- if (this.useSourceMap || this.useSimpleSourceMap) {
- sources.set(
- "javascript",
- new OriginalSource(sourceString, this.identifier())
- );
- } else {
- sources.set("javascript", new RawSource(sourceString));
- }
- let runtimeRequirements = sourceData.runtimeRequirements;
- if (!concatenationScope) {
- if (!runtimeRequirements) {
- runtimeRequirements = RUNTIME_REQUIREMENTS;
- } else {
- const set = new Set(runtimeRequirements);
- set.add(RuntimeGlobals.module);
- runtimeRequirements = set;
- }
- }
- return {
- sources,
- runtimeRequirements:
- runtimeRequirements || EMPTY_RUNTIME_REQUIREMENTS,
- data
- };
- }
- }
- }
- /**
- * @param {string=} type the source type for which the size should be estimated
- * @returns {number} the estimated size of the module (must be non-zero)
- */
- size(type) {
- return 42;
- }
- /**
- * @param {Hash} hash the hash used to track dependencies
- * @param {UpdateHashContext} context context
- * @returns {void}
- */
- updateHash(hash, context) {
- const { chunkGraph } = context;
- hash.update(
- `${this.externalType}${JSON.stringify(this.request)}${this.isOptional(
- chunkGraph.moduleGraph
- )}`
- );
- super.updateHash(hash, context);
- }
- /**
- * @param {ObjectSerializerContext} context context
- */
- serialize(context) {
- const { write } = context;
- write(this.request);
- write(this.externalType);
- write(this.userRequest);
- write(this.dependencyMeta);
- super.serialize(context);
- }
- /**
- * @param {ObjectDeserializerContext} context context
- */
- deserialize(context) {
- const { read } = context;
- this.request = read();
- this.externalType = read();
- this.userRequest = read();
- this.dependencyMeta = read();
- super.deserialize(context);
- }
- }
- makeSerializable(ExternalModule, "webpack/lib/ExternalModule");
- module.exports = ExternalModule;
|