source: imaps-frontend/node_modules/webpack/lib/ExternalModule.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 29.2 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const { OriginalSource, RawSource } = require("webpack-sources");
9const ConcatenationScope = require("./ConcatenationScope");
10const EnvironmentNotSupportAsyncWarning = require("./EnvironmentNotSupportAsyncWarning");
11const { UsageState } = require("./ExportsInfo");
12const InitFragment = require("./InitFragment");
13const Module = require("./Module");
14const {
15 JS_TYPES,
16 CSS_URL_TYPES,
17 CSS_IMPORT_TYPES
18} = require("./ModuleSourceTypesConstants");
19const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants");
20const RuntimeGlobals = require("./RuntimeGlobals");
21const Template = require("./Template");
22const StaticExportsDependency = require("./dependencies/StaticExportsDependency");
23const createHash = require("./util/createHash");
24const extractUrlAndGlobal = require("./util/extractUrlAndGlobal");
25const makeSerializable = require("./util/makeSerializable");
26const propertyAccess = require("./util/propertyAccess");
27const { register } = require("./util/serialization");
28
29/** @typedef {import("webpack-sources").Source} Source */
30/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
31/** @typedef {import("./Chunk")} Chunk */
32/** @typedef {import("./ChunkGraph")} ChunkGraph */
33/** @typedef {import("./Compilation")} Compilation */
34/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
35/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
36/** @typedef {import("./ExportsInfo")} ExportsInfo */
37/** @typedef {import("./Generator").GenerateContext} GenerateContext */
38/** @typedef {import("./Generator").SourceTypes} SourceTypes */
39/** @typedef {import("./Module").BuildInfo} BuildInfo */
40/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
41/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
42/** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
43/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
44/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
45/** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
46/** @typedef {import("./ModuleGraph")} ModuleGraph */
47/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
48/** @typedef {import("./RequestShortener")} RequestShortener */
49/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
50/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
51/** @typedef {import("./WebpackError")} WebpackError */
52/** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
53/** @typedef {import("./javascript/JavascriptParser").ImportAttributes} ImportAttributes */
54/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
55/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
56/** @typedef {import("./util/Hash")} Hash */
57/** @typedef {typeof import("./util/Hash")} HashConstructor */
58/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
59/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
60
61/** @typedef {{ attributes?: ImportAttributes, externalType: "import" | "module" | undefined }} ImportDependencyMeta */
62/** @typedef {{ layer?: string, supports?: string, media?: string }} CssImportDependencyMeta */
63/** @typedef {{ sourceType: "css-url" }} AssetDependencyMeta */
64
65/** @typedef {ImportDependencyMeta | CssImportDependencyMeta | AssetDependencyMeta} DependencyMeta */
66
67/**
68 * @typedef {object} SourceData
69 * @property {boolean=} iife
70 * @property {string=} init
71 * @property {string} expression
72 * @property {InitFragment<ChunkRenderContext>[]=} chunkInitFragments
73 * @property {ReadOnlyRuntimeRequirements=} runtimeRequirements
74 */
75
76const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
77const RUNTIME_REQUIREMENTS_FOR_SCRIPT = new Set([RuntimeGlobals.loadScript]);
78const RUNTIME_REQUIREMENTS_FOR_MODULE = new Set([
79 RuntimeGlobals.definePropertyGetters
80]);
81const EMPTY_RUNTIME_REQUIREMENTS = new Set([]);
82
83/**
84 * @param {string|string[]} variableName the variable name or path
85 * @param {string} type the module system
86 * @returns {SourceData} the generated source
87 */
88const getSourceForGlobalVariableExternal = (variableName, type) => {
89 if (!Array.isArray(variableName)) {
90 // make it an array as the look up works the same basically
91 variableName = [variableName];
92 }
93
94 // needed for e.g. window["some"]["thing"]
95 const objectLookup = variableName.map(r => `[${JSON.stringify(r)}]`).join("");
96 return {
97 iife: type === "this",
98 expression: `${type}${objectLookup}`
99 };
100};
101
102/**
103 * @param {string|string[]} moduleAndSpecifiers the module request
104 * @returns {SourceData} the generated source
105 */
106const getSourceForCommonJsExternal = moduleAndSpecifiers => {
107 if (!Array.isArray(moduleAndSpecifiers)) {
108 return {
109 expression: `require(${JSON.stringify(moduleAndSpecifiers)})`
110 };
111 }
112 const moduleName = moduleAndSpecifiers[0];
113 return {
114 expression: `require(${JSON.stringify(moduleName)})${propertyAccess(
115 moduleAndSpecifiers,
116 1
117 )}`
118 };
119};
120
121/**
122 * @param {string|string[]} moduleAndSpecifiers the module request
123 * @param {string} importMetaName import.meta name
124 * @param {boolean} needPrefix need to use `node:` prefix for `module` import
125 * @returns {SourceData} the generated source
126 */
127const getSourceForCommonJsExternalInNodeModule = (
128 moduleAndSpecifiers,
129 importMetaName,
130 needPrefix
131) => {
132 const chunkInitFragments = [
133 new InitFragment(
134 `import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "${
135 needPrefix ? "node:" : ""
136 }module";\n`,
137 InitFragment.STAGE_HARMONY_IMPORTS,
138 0,
139 "external module node-commonjs"
140 )
141 ];
142 if (!Array.isArray(moduleAndSpecifiers)) {
143 return {
144 chunkInitFragments,
145 expression: `__WEBPACK_EXTERNAL_createRequire(${importMetaName}.url)(${JSON.stringify(
146 moduleAndSpecifiers
147 )})`
148 };
149 }
150 const moduleName = moduleAndSpecifiers[0];
151 return {
152 chunkInitFragments,
153 expression: `__WEBPACK_EXTERNAL_createRequire(${importMetaName}.url)(${JSON.stringify(
154 moduleName
155 )})${propertyAccess(moduleAndSpecifiers, 1)}`
156 };
157};
158
159/**
160 * @param {string|string[]} moduleAndSpecifiers the module request
161 * @param {RuntimeTemplate} runtimeTemplate the runtime template
162 * @param {ImportDependencyMeta=} dependencyMeta the dependency meta
163 * @returns {SourceData} the generated source
164 */
165const getSourceForImportExternal = (
166 moduleAndSpecifiers,
167 runtimeTemplate,
168 dependencyMeta
169) => {
170 const importName = runtimeTemplate.outputOptions.importFunctionName;
171 if (
172 !runtimeTemplate.supportsDynamicImport() &&
173 (importName === "import" || importName === "module-import")
174 ) {
175 throw new Error(
176 "The target environment doesn't support 'import()' so it's not possible to use external type 'import'"
177 );
178 }
179 const attributes =
180 dependencyMeta && dependencyMeta.attributes
181 ? dependencyMeta.attributes._isLegacyAssert
182 ? `, { assert: ${JSON.stringify(
183 dependencyMeta.attributes,
184 importAssertionReplacer
185 )} }`
186 : `, { with: ${JSON.stringify(dependencyMeta.attributes)} }`
187 : "";
188 if (!Array.isArray(moduleAndSpecifiers)) {
189 return {
190 expression: `${importName}(${JSON.stringify(
191 moduleAndSpecifiers
192 )}${attributes});`
193 };
194 }
195 if (moduleAndSpecifiers.length === 1) {
196 return {
197 expression: `${importName}(${JSON.stringify(
198 moduleAndSpecifiers[0]
199 )}${attributes});`
200 };
201 }
202 const moduleName = moduleAndSpecifiers[0];
203 return {
204 expression: `${importName}(${JSON.stringify(
205 moduleName
206 )}${attributes}).then(${runtimeTemplate.returningFunction(
207 `module${propertyAccess(moduleAndSpecifiers, 1)}`,
208 "module"
209 )});`
210 };
211};
212
213/**
214 * @param {string} key key
215 * @param {any | undefined} value value
216 * @returns {undefined | string} replaced value
217 */
218const importAssertionReplacer = (key, value) => {
219 if (key === "_isLegacyAssert") {
220 return;
221 }
222
223 return value;
224};
225
226/**
227 * @extends {InitFragment<ChunkRenderContext>}
228 */
229class ModuleExternalInitFragment extends InitFragment {
230 /**
231 * @param {string} request import source
232 * @param {string=} ident recomputed ident
233 * @param {ImportDependencyMeta=} dependencyMeta the dependency meta
234 * @param {string | HashConstructor=} hashFunction the hash function to use
235 */
236 constructor(request, ident, dependencyMeta, hashFunction = "md4") {
237 if (ident === undefined) {
238 ident = Template.toIdentifier(request);
239 if (ident !== request) {
240 ident += `_${createHash(hashFunction)
241 .update(request)
242 .digest("hex")
243 .slice(0, 8)}`;
244 }
245 }
246 const identifier = `__WEBPACK_EXTERNAL_MODULE_${ident}__`;
247 super(
248 `import * as ${identifier} from ${JSON.stringify(request)}${
249 dependencyMeta && dependencyMeta.attributes
250 ? dependencyMeta.attributes._isLegacyAssert
251 ? ` assert ${JSON.stringify(
252 dependencyMeta.attributes,
253 importAssertionReplacer
254 )}`
255 : ` with ${JSON.stringify(dependencyMeta.attributes)}`
256 : ""
257 };\n`,
258 InitFragment.STAGE_HARMONY_IMPORTS,
259 0,
260 `external module import ${ident}`
261 );
262 this._ident = ident;
263 this._request = request;
264 this._dependencyMeta = request;
265 this._identifier = identifier;
266 }
267
268 getNamespaceIdentifier() {
269 return this._identifier;
270 }
271}
272
273register(
274 ModuleExternalInitFragment,
275 "webpack/lib/ExternalModule",
276 "ModuleExternalInitFragment",
277 {
278 serialize(obj, { write }) {
279 write(obj._request);
280 write(obj._ident);
281 write(obj._dependencyMeta);
282 },
283 deserialize({ read }) {
284 return new ModuleExternalInitFragment(read(), read(), read());
285 }
286 }
287);
288
289/**
290 * @param {string} input input
291 * @param {ExportsInfo} exportsInfo the exports info
292 * @param {RuntimeSpec=} runtime the runtime
293 * @param {RuntimeTemplate=} runtimeTemplate the runtime template
294 * @returns {string | undefined} the module remapping
295 */
296const generateModuleRemapping = (
297 input,
298 exportsInfo,
299 runtime,
300 runtimeTemplate
301) => {
302 if (exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused) {
303 const properties = [];
304 for (const exportInfo of exportsInfo.orderedExports) {
305 const used = exportInfo.getUsedName(exportInfo.name, runtime);
306 if (!used) continue;
307 const nestedInfo = exportInfo.getNestedExportsInfo();
308 if (nestedInfo) {
309 const nestedExpr = generateModuleRemapping(
310 `${input}${propertyAccess([exportInfo.name])}`,
311 nestedInfo
312 );
313 if (nestedExpr) {
314 properties.push(`[${JSON.stringify(used)}]: y(${nestedExpr})`);
315 continue;
316 }
317 }
318 properties.push(
319 `[${JSON.stringify(used)}]: ${
320 /** @type {RuntimeTemplate} */ (runtimeTemplate).returningFunction(
321 `${input}${propertyAccess([exportInfo.name])}`
322 )
323 }`
324 );
325 }
326 return `x({ ${properties.join(", ")} })`;
327 }
328};
329
330/**
331 * @param {string|string[]} moduleAndSpecifiers the module request
332 * @param {ExportsInfo} exportsInfo exports info of this module
333 * @param {RuntimeSpec} runtime the runtime
334 * @param {RuntimeTemplate} runtimeTemplate the runtime template
335 * @param {ImportDependencyMeta} dependencyMeta the dependency meta
336 * @returns {SourceData} the generated source
337 */
338const getSourceForModuleExternal = (
339 moduleAndSpecifiers,
340 exportsInfo,
341 runtime,
342 runtimeTemplate,
343 dependencyMeta
344) => {
345 if (!Array.isArray(moduleAndSpecifiers))
346 moduleAndSpecifiers = [moduleAndSpecifiers];
347 const initFragment = new ModuleExternalInitFragment(
348 moduleAndSpecifiers[0],
349 undefined,
350 dependencyMeta,
351 runtimeTemplate.outputOptions.hashFunction
352 );
353 const baseAccess = `${initFragment.getNamespaceIdentifier()}${propertyAccess(
354 moduleAndSpecifiers,
355 1
356 )}`;
357 const moduleRemapping = generateModuleRemapping(
358 baseAccess,
359 exportsInfo,
360 runtime,
361 runtimeTemplate
362 );
363 const expression = moduleRemapping || baseAccess;
364 return {
365 expression,
366 init: moduleRemapping
367 ? `var x = ${runtimeTemplate.basicFunction(
368 "y",
369 `var x = {}; ${RuntimeGlobals.definePropertyGetters}(x, y); return x`
370 )} \nvar y = ${runtimeTemplate.returningFunction(
371 runtimeTemplate.returningFunction("x"),
372 "x"
373 )}`
374 : undefined,
375 runtimeRequirements: moduleRemapping
376 ? RUNTIME_REQUIREMENTS_FOR_MODULE
377 : undefined,
378 chunkInitFragments: [initFragment]
379 };
380};
381
382/**
383 * @param {string|string[]} urlAndGlobal the script request
384 * @param {RuntimeTemplate} runtimeTemplate the runtime template
385 * @returns {SourceData} the generated source
386 */
387const getSourceForScriptExternal = (urlAndGlobal, runtimeTemplate) => {
388 if (typeof urlAndGlobal === "string") {
389 urlAndGlobal = extractUrlAndGlobal(urlAndGlobal);
390 }
391 const url = urlAndGlobal[0];
392 const globalName = urlAndGlobal[1];
393 return {
394 init: "var __webpack_error__ = new Error();",
395 expression: `new Promise(${runtimeTemplate.basicFunction(
396 "resolve, reject",
397 [
398 `if(typeof ${globalName} !== "undefined") return resolve();`,
399 `${RuntimeGlobals.loadScript}(${JSON.stringify(
400 url
401 )}, ${runtimeTemplate.basicFunction("event", [
402 `if(typeof ${globalName} !== "undefined") return resolve();`,
403 "var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
404 "var realSrc = event && event.target && event.target.src;",
405 "__webpack_error__.message = 'Loading script failed.\\n(' + errorType + ': ' + realSrc + ')';",
406 "__webpack_error__.name = 'ScriptExternalLoadError';",
407 "__webpack_error__.type = errorType;",
408 "__webpack_error__.request = realSrc;",
409 "reject(__webpack_error__);"
410 ])}, ${JSON.stringify(globalName)});`
411 ]
412 )}).then(${runtimeTemplate.returningFunction(
413 `${globalName}${propertyAccess(urlAndGlobal, 2)}`
414 )})`,
415 runtimeRequirements: RUNTIME_REQUIREMENTS_FOR_SCRIPT
416 };
417};
418
419/**
420 * @param {string} variableName the variable name to check
421 * @param {string} request the request path
422 * @param {RuntimeTemplate} runtimeTemplate the runtime template
423 * @returns {string} the generated source
424 */
425const checkExternalVariable = (variableName, request, runtimeTemplate) =>
426 `if(typeof ${variableName} === 'undefined') { ${runtimeTemplate.throwMissingModuleErrorBlock(
427 { request }
428 )} }\n`;
429
430/**
431 * @param {string|number} id the module id
432 * @param {boolean} optional true, if the module is optional
433 * @param {string|string[]} request the request path
434 * @param {RuntimeTemplate} runtimeTemplate the runtime template
435 * @returns {SourceData} the generated source
436 */
437const getSourceForAmdOrUmdExternal = (
438 id,
439 optional,
440 request,
441 runtimeTemplate
442) => {
443 const externalVariable = `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
444 `${id}`
445 )}__`;
446 return {
447 init: optional
448 ? checkExternalVariable(
449 externalVariable,
450 Array.isArray(request) ? request.join(".") : request,
451 runtimeTemplate
452 )
453 : undefined,
454 expression: externalVariable
455 };
456};
457
458/**
459 * @param {boolean} optional true, if the module is optional
460 * @param {string|string[]} request the request path
461 * @param {RuntimeTemplate} runtimeTemplate the runtime template
462 * @returns {SourceData} the generated source
463 */
464const getSourceForDefaultCase = (optional, request, runtimeTemplate) => {
465 if (!Array.isArray(request)) {
466 // make it an array as the look up works the same basically
467 request = [request];
468 }
469
470 const variableName = request[0];
471 const objectLookup = propertyAccess(request, 1);
472 return {
473 init: optional
474 ? checkExternalVariable(variableName, request.join("."), runtimeTemplate)
475 : undefined,
476 expression: `${variableName}${objectLookup}`
477 };
478};
479
480/** @typedef {Record<string, string | string[]>} RequestRecord */
481
482class ExternalModule extends Module {
483 /**
484 * @param {string | string[] | RequestRecord} request request
485 * @param {string} type type
486 * @param {string} userRequest user request
487 * @param {DependencyMeta=} dependencyMeta dependency meta
488 */
489 constructor(request, type, userRequest, dependencyMeta) {
490 super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null);
491
492 // Info from Factory
493 /** @type {string | string[] | Record<string, string | string[]>} */
494 this.request = request;
495 /** @type {string} */
496 this.externalType = type;
497 /** @type {string} */
498 this.userRequest = userRequest;
499 /** @type {DependencyMeta=} */
500 this.dependencyMeta = dependencyMeta;
501 }
502
503 /**
504 * @returns {SourceTypes} types available (do not mutate)
505 */
506 getSourceTypes() {
507 if (
508 this.externalType === "asset" &&
509 this.dependencyMeta &&
510 /** @type {AssetDependencyMeta} */
511 (this.dependencyMeta).sourceType === "css-url"
512 ) {
513 return CSS_URL_TYPES;
514 } else if (this.externalType === "css-import") {
515 return CSS_IMPORT_TYPES;
516 }
517
518 return JS_TYPES;
519 }
520
521 /**
522 * @param {LibIdentOptions} options options
523 * @returns {string | null} an identifier for library inclusion
524 */
525 libIdent(options) {
526 return this.userRequest;
527 }
528
529 /**
530 * @param {Chunk} chunk the chunk which condition should be checked
531 * @param {Compilation} compilation the compilation
532 * @returns {boolean} true, if the chunk is ok for the module
533 */
534 chunkCondition(chunk, { chunkGraph }) {
535 return this.externalType === "css-import"
536 ? true
537 : chunkGraph.getNumberOfEntryModules(chunk) > 0;
538 }
539
540 /**
541 * @returns {string} a unique identifier of the module
542 */
543 identifier() {
544 return `external ${this._resolveExternalType(this.externalType)} ${JSON.stringify(this.request)}`;
545 }
546
547 /**
548 * @param {RequestShortener} requestShortener the request shortener
549 * @returns {string} a user readable identifier of the module
550 */
551 readableIdentifier(requestShortener) {
552 return `external ${JSON.stringify(this.request)}`;
553 }
554
555 /**
556 * @param {NeedBuildContext} context context info
557 * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
558 * @returns {void}
559 */
560 needBuild(context, callback) {
561 return callback(null, !this.buildMeta);
562 }
563
564 /**
565 * @param {WebpackOptions} options webpack options
566 * @param {Compilation} compilation the compilation
567 * @param {ResolverWithOptions} resolver the resolver
568 * @param {InputFileSystem} fs the file system
569 * @param {function(WebpackError=): void} callback callback function
570 * @returns {void}
571 */
572 build(options, compilation, resolver, fs, callback) {
573 this.buildMeta = {
574 async: false,
575 exportsType: undefined
576 };
577 this.buildInfo = {
578 strict: true,
579 topLevelDeclarations: new Set(),
580 module: compilation.outputOptions.module
581 };
582 const { request, externalType } = this._getRequestAndExternalType();
583 this.buildMeta.exportsType = "dynamic";
584 let canMangle = false;
585 this.clearDependenciesAndBlocks();
586 switch (externalType) {
587 case "this":
588 this.buildInfo.strict = false;
589 break;
590 case "system":
591 if (!Array.isArray(request) || request.length === 1) {
592 this.buildMeta.exportsType = "namespace";
593 canMangle = true;
594 }
595 break;
596 case "module":
597 if (this.buildInfo.module) {
598 if (!Array.isArray(request) || request.length === 1) {
599 this.buildMeta.exportsType = "namespace";
600 canMangle = true;
601 }
602 } else {
603 this.buildMeta.async = true;
604 EnvironmentNotSupportAsyncWarning.check(
605 this,
606 compilation.runtimeTemplate,
607 "external module"
608 );
609 if (!Array.isArray(request) || request.length === 1) {
610 this.buildMeta.exportsType = "namespace";
611 canMangle = false;
612 }
613 }
614 break;
615 case "script":
616 this.buildMeta.async = true;
617 EnvironmentNotSupportAsyncWarning.check(
618 this,
619 compilation.runtimeTemplate,
620 "external script"
621 );
622 break;
623 case "promise":
624 this.buildMeta.async = true;
625 EnvironmentNotSupportAsyncWarning.check(
626 this,
627 compilation.runtimeTemplate,
628 "external promise"
629 );
630 break;
631 case "import":
632 this.buildMeta.async = true;
633 EnvironmentNotSupportAsyncWarning.check(
634 this,
635 compilation.runtimeTemplate,
636 "external import"
637 );
638 if (!Array.isArray(request) || request.length === 1) {
639 this.buildMeta.exportsType = "namespace";
640 canMangle = false;
641 }
642 break;
643 }
644 this.addDependency(new StaticExportsDependency(true, canMangle));
645 callback();
646 }
647
648 /**
649 * restore unsafe cache data
650 * @param {object} unsafeCacheData data from getUnsafeCacheData
651 * @param {NormalModuleFactory} normalModuleFactory the normal module factory handling the unsafe caching
652 */
653 restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory) {
654 this._restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory);
655 }
656
657 /**
658 * @param {ConcatenationBailoutReasonContext} context context
659 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
660 */
661 getConcatenationBailoutReason({ moduleGraph }) {
662 switch (this.externalType) {
663 case "amd":
664 case "amd-require":
665 case "umd":
666 case "umd2":
667 case "system":
668 case "jsonp":
669 return `${this.externalType} externals can't be concatenated`;
670 }
671 return undefined;
672 }
673
674 _getRequestAndExternalType() {
675 let { request, externalType } = this;
676 if (typeof request === "object" && !Array.isArray(request))
677 request = request[externalType];
678 externalType = this._resolveExternalType(externalType);
679 return { request, externalType };
680 }
681
682 /**
683 * Resolve the detailed external type from the raw external type.
684 * e.g. resolve "module" or "import" from "module-import" type
685 * @param {string} externalType raw external type
686 * @returns {string} resolved external type
687 */
688 _resolveExternalType(externalType) {
689 if (externalType === "module-import") {
690 if (
691 this.dependencyMeta &&
692 /** @type {ImportDependencyMeta} */
693 (this.dependencyMeta).externalType
694 ) {
695 return /** @type {ImportDependencyMeta} */ (this.dependencyMeta)
696 .externalType;
697 }
698 return "module";
699 } else if (externalType === "asset") {
700 if (
701 this.dependencyMeta &&
702 /** @type {AssetDependencyMeta} */
703 (this.dependencyMeta).sourceType
704 ) {
705 return /** @type {AssetDependencyMeta} */ (this.dependencyMeta)
706 .sourceType;
707 }
708
709 return "asset";
710 }
711
712 return externalType;
713 }
714
715 /**
716 * @private
717 * @param {string | string[]} request request
718 * @param {string} externalType the external type
719 * @param {RuntimeTemplate} runtimeTemplate the runtime template
720 * @param {ModuleGraph} moduleGraph the module graph
721 * @param {ChunkGraph} chunkGraph the chunk graph
722 * @param {RuntimeSpec} runtime the runtime
723 * @param {DependencyMeta | undefined} dependencyMeta the dependency meta
724 * @returns {SourceData} the source data
725 */
726 _getSourceData(
727 request,
728 externalType,
729 runtimeTemplate,
730 moduleGraph,
731 chunkGraph,
732 runtime,
733 dependencyMeta
734 ) {
735 switch (externalType) {
736 case "this":
737 case "window":
738 case "self":
739 return getSourceForGlobalVariableExternal(request, this.externalType);
740 case "global":
741 return getSourceForGlobalVariableExternal(
742 request,
743 runtimeTemplate.globalObject
744 );
745 case "commonjs":
746 case "commonjs2":
747 case "commonjs-module":
748 case "commonjs-static":
749 return getSourceForCommonJsExternal(request);
750 case "node-commonjs":
751 return /** @type {BuildInfo} */ (this.buildInfo).module
752 ? getSourceForCommonJsExternalInNodeModule(
753 request,
754 /** @type {string} */
755 (runtimeTemplate.outputOptions.importMetaName),
756 /** @type {boolean} */
757 (runtimeTemplate.supportNodePrefixForCoreModules())
758 )
759 : getSourceForCommonJsExternal(request);
760 case "amd":
761 case "amd-require":
762 case "umd":
763 case "umd2":
764 case "system":
765 case "jsonp": {
766 const id = chunkGraph.getModuleId(this);
767 return getSourceForAmdOrUmdExternal(
768 id !== null ? id : this.identifier(),
769 this.isOptional(moduleGraph),
770 request,
771 runtimeTemplate
772 );
773 }
774 case "import":
775 return getSourceForImportExternal(
776 request,
777 runtimeTemplate,
778 /** @type {ImportDependencyMeta} */ (dependencyMeta)
779 );
780 case "script":
781 return getSourceForScriptExternal(request, runtimeTemplate);
782 case "module": {
783 if (!(/** @type {BuildInfo} */ (this.buildInfo).module)) {
784 if (!runtimeTemplate.supportsDynamicImport()) {
785 throw new Error(
786 `The target environment doesn't support dynamic import() syntax so it's not possible to use external type 'module' within a script${
787 runtimeTemplate.supportsEcmaScriptModuleSyntax()
788 ? "\nDid you mean to build a EcmaScript Module ('output.module: true')?"
789 : ""
790 }`
791 );
792 }
793 return getSourceForImportExternal(
794 request,
795 runtimeTemplate,
796 /** @type {ImportDependencyMeta} */ (dependencyMeta)
797 );
798 }
799 if (!runtimeTemplate.supportsEcmaScriptModuleSyntax()) {
800 throw new Error(
801 "The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module'"
802 );
803 }
804 return getSourceForModuleExternal(
805 request,
806 moduleGraph.getExportsInfo(this),
807 runtime,
808 runtimeTemplate,
809 /** @type {ImportDependencyMeta} */ (dependencyMeta)
810 );
811 }
812 case "var":
813 case "promise":
814 case "const":
815 case "let":
816 case "assign":
817 default:
818 return getSourceForDefaultCase(
819 this.isOptional(moduleGraph),
820 request,
821 runtimeTemplate
822 );
823 }
824 }
825
826 /**
827 * @param {CodeGenerationContext} context context for code generation
828 * @returns {CodeGenerationResult} result
829 */
830 codeGeneration({
831 runtimeTemplate,
832 moduleGraph,
833 chunkGraph,
834 runtime,
835 concatenationScope
836 }) {
837 const { request, externalType } = this._getRequestAndExternalType();
838 switch (externalType) {
839 case "asset": {
840 const sources = new Map();
841 sources.set(
842 "javascript",
843 new RawSource(`module.exports = ${JSON.stringify(request)};`)
844 );
845 const data = new Map();
846 data.set("url", { javascript: request });
847 return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS, data };
848 }
849 case "css-url": {
850 const sources = new Map();
851 const data = new Map();
852 data.set("url", { "css-url": request });
853 return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS, data };
854 }
855 case "css-import": {
856 const sources = new Map();
857 const dependencyMeta = /** @type {CssImportDependencyMeta} */ (
858 this.dependencyMeta
859 );
860 const layer =
861 dependencyMeta.layer !== undefined
862 ? ` layer(${dependencyMeta.layer})`
863 : "";
864 const supports = dependencyMeta.supports
865 ? ` supports(${dependencyMeta.supports})`
866 : "";
867 const media = dependencyMeta.media ? ` ${dependencyMeta.media}` : "";
868 sources.set(
869 "css-import",
870 new RawSource(
871 `@import url(${JSON.stringify(
872 request
873 )})${layer}${supports}${media};`
874 )
875 );
876 return {
877 sources,
878 runtimeRequirements: EMPTY_RUNTIME_REQUIREMENTS
879 };
880 }
881 default: {
882 const sourceData = this._getSourceData(
883 request,
884 externalType,
885 runtimeTemplate,
886 moduleGraph,
887 chunkGraph,
888 runtime,
889 this.dependencyMeta
890 );
891
892 let sourceString = sourceData.expression;
893 if (sourceData.iife)
894 sourceString = `(function() { return ${sourceString}; }())`;
895 if (concatenationScope) {
896 sourceString = `${
897 runtimeTemplate.supportsConst() ? "const" : "var"
898 } ${ConcatenationScope.NAMESPACE_OBJECT_EXPORT} = ${sourceString};`;
899 concatenationScope.registerNamespaceExport(
900 ConcatenationScope.NAMESPACE_OBJECT_EXPORT
901 );
902 } else {
903 sourceString = `module.exports = ${sourceString};`;
904 }
905 if (sourceData.init)
906 sourceString = `${sourceData.init}\n${sourceString}`;
907
908 let data;
909 if (sourceData.chunkInitFragments) {
910 data = new Map();
911 data.set("chunkInitFragments", sourceData.chunkInitFragments);
912 }
913
914 const sources = new Map();
915 if (this.useSourceMap || this.useSimpleSourceMap) {
916 sources.set(
917 "javascript",
918 new OriginalSource(sourceString, this.identifier())
919 );
920 } else {
921 sources.set("javascript", new RawSource(sourceString));
922 }
923
924 let runtimeRequirements = sourceData.runtimeRequirements;
925 if (!concatenationScope) {
926 if (!runtimeRequirements) {
927 runtimeRequirements = RUNTIME_REQUIREMENTS;
928 } else {
929 const set = new Set(runtimeRequirements);
930 set.add(RuntimeGlobals.module);
931 runtimeRequirements = set;
932 }
933 }
934
935 return {
936 sources,
937 runtimeRequirements:
938 runtimeRequirements || EMPTY_RUNTIME_REQUIREMENTS,
939 data
940 };
941 }
942 }
943 }
944
945 /**
946 * @param {string=} type the source type for which the size should be estimated
947 * @returns {number} the estimated size of the module (must be non-zero)
948 */
949 size(type) {
950 return 42;
951 }
952
953 /**
954 * @param {Hash} hash the hash used to track dependencies
955 * @param {UpdateHashContext} context context
956 * @returns {void}
957 */
958 updateHash(hash, context) {
959 const { chunkGraph } = context;
960 hash.update(
961 `${this._resolveExternalType(this.externalType)}${JSON.stringify(this.request)}${this.isOptional(
962 chunkGraph.moduleGraph
963 )}`
964 );
965 super.updateHash(hash, context);
966 }
967
968 /**
969 * @param {ObjectSerializerContext} context context
970 */
971 serialize(context) {
972 const { write } = context;
973
974 write(this.request);
975 write(this.externalType);
976 write(this.userRequest);
977 write(this.dependencyMeta);
978
979 super.serialize(context);
980 }
981
982 /**
983 * @param {ObjectDeserializerContext} context context
984 */
985 deserialize(context) {
986 const { read } = context;
987
988 this.request = read();
989 this.externalType = read();
990 this.userRequest = read();
991 this.dependencyMeta = read();
992
993 super.deserialize(context);
994 }
995}
996
997makeSerializable(ExternalModule, "webpack/lib/ExternalModule");
998
999module.exports = ExternalModule;
Note: See TracBrowser for help on using the repository browser.