source: trip-planner-front/node_modules/webpack/lib/ExternalModule.js@ 6c1585f

Last change on this file since 6c1585f was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 20.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 { UsageState } = require("./ExportsInfo");
11const InitFragment = require("./InitFragment");
12const Module = require("./Module");
13const RuntimeGlobals = require("./RuntimeGlobals");
14const Template = require("./Template");
15const StaticExportsDependency = require("./dependencies/StaticExportsDependency");
16const extractUrlAndGlobal = require("./util/extractUrlAndGlobal");
17const makeSerializable = require("./util/makeSerializable");
18const propertyAccess = require("./util/propertyAccess");
19const { register } = require("./util/serialization");
20
21/** @typedef {import("webpack-sources").Source} Source */
22/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
23/** @typedef {import("./Chunk")} Chunk */
24/** @typedef {import("./ChunkGraph")} ChunkGraph */
25/** @typedef {import("./Compilation")} Compilation */
26/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
27/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
28/** @typedef {import("./ExportsInfo")} ExportsInfo */
29/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
30/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
31/** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
32/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
33/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
34/** @typedef {import("./RequestShortener")} RequestShortener */
35/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
36/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
37/** @typedef {import("./WebpackError")} WebpackError */
38/** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
39/** @typedef {import("./util/Hash")} Hash */
40/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
41/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
42
43/**
44 * @typedef {Object} SourceData
45 * @property {boolean=} iife
46 * @property {string=} init
47 * @property {string} expression
48 * @property {InitFragment<ChunkRenderContext>[]=} chunkInitFragments
49 * @property {ReadonlySet<string>=} runtimeRequirements
50 */
51
52const TYPES = new Set(["javascript"]);
53const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
54const RUNTIME_REQUIREMENTS_FOR_SCRIPT = new Set([RuntimeGlobals.loadScript]);
55const RUNTIME_REQUIREMENTS_FOR_MODULE = new Set([
56 RuntimeGlobals.definePropertyGetters
57]);
58const EMPTY_RUNTIME_REQUIREMENTS = new Set([]);
59
60/**
61 * @param {string|string[]} variableName the variable name or path
62 * @param {string} type the module system
63 * @returns {SourceData} the generated source
64 */
65const getSourceForGlobalVariableExternal = (variableName, type) => {
66 if (!Array.isArray(variableName)) {
67 // make it an array as the look up works the same basically
68 variableName = [variableName];
69 }
70
71 // needed for e.g. window["some"]["thing"]
72 const objectLookup = variableName.map(r => `[${JSON.stringify(r)}]`).join("");
73 return {
74 iife: type === "this",
75 expression: `${type}${objectLookup}`
76 };
77};
78
79/**
80 * @param {string|string[]} moduleAndSpecifiers the module request
81 * @returns {SourceData} the generated source
82 */
83const getSourceForCommonJsExternal = moduleAndSpecifiers => {
84 if (!Array.isArray(moduleAndSpecifiers)) {
85 return {
86 expression: `require(${JSON.stringify(moduleAndSpecifiers)})`
87 };
88 }
89 const moduleName = moduleAndSpecifiers[0];
90 return {
91 expression: `require(${JSON.stringify(moduleName)})${propertyAccess(
92 moduleAndSpecifiers,
93 1
94 )}`
95 };
96};
97
98/**
99 * @param {string|string[]} moduleAndSpecifiers the module request
100 * @returns {SourceData} the generated source
101 */
102const getSourceForCommonJsExternalInNodeModule = moduleAndSpecifiers => {
103 const chunkInitFragments = [
104 new InitFragment(
105 'import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "module";\n',
106 InitFragment.STAGE_HARMONY_IMPORTS,
107 0,
108 "external module node-commonjs"
109 )
110 ];
111 if (!Array.isArray(moduleAndSpecifiers)) {
112 return {
113 expression: `__WEBPACK_EXTERNAL_createRequire(import.meta.url)(${JSON.stringify(
114 moduleAndSpecifiers
115 )})`,
116 chunkInitFragments
117 };
118 }
119 const moduleName = moduleAndSpecifiers[0];
120 return {
121 expression: `__WEBPACK_EXTERNAL_createRequire(import.meta.url)(${JSON.stringify(
122 moduleName
123 )})${propertyAccess(moduleAndSpecifiers, 1)}`,
124 chunkInitFragments
125 };
126};
127
128/**
129 * @param {string|string[]} moduleAndSpecifiers the module request
130 * @param {RuntimeTemplate} runtimeTemplate the runtime template
131 * @returns {SourceData} the generated source
132 */
133const getSourceForImportExternal = (moduleAndSpecifiers, runtimeTemplate) => {
134 const importName = runtimeTemplate.outputOptions.importFunctionName;
135 if (!runtimeTemplate.supportsDynamicImport() && importName === "import") {
136 throw new Error(
137 "The target environment doesn't support 'import()' so it's not possible to use external type 'import'"
138 );
139 }
140 if (!Array.isArray(moduleAndSpecifiers)) {
141 return {
142 expression: `${importName}(${JSON.stringify(moduleAndSpecifiers)});`
143 };
144 }
145 if (moduleAndSpecifiers.length === 1) {
146 return {
147 expression: `${importName}(${JSON.stringify(moduleAndSpecifiers[0])});`
148 };
149 }
150 const moduleName = moduleAndSpecifiers[0];
151 return {
152 expression: `${importName}(${JSON.stringify(
153 moduleName
154 )}).then(${runtimeTemplate.returningFunction(
155 `module${propertyAccess(moduleAndSpecifiers, 1)}`,
156 "module"
157 )});`
158 };
159};
160
161class ModuleExternalInitFragment extends InitFragment {
162 constructor(id, request) {
163 const identifier = `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
164 `${id}`
165 )}__`;
166 super(
167 `import * as ${identifier} from ${JSON.stringify(request)};\n`,
168 InitFragment.STAGE_HARMONY_IMPORTS,
169 0,
170 `external module import ${id}`
171 );
172 this._identifier = identifier;
173 this._id = id;
174 this._request = request;
175 }
176
177 getNamespaceIdentifier() {
178 return this._identifier;
179 }
180}
181
182register(
183 ModuleExternalInitFragment,
184 "webpack/lib/ExternalModule",
185 "ModuleExternalInitFragment",
186 {
187 serialize(obj, { write }) {
188 write(obj._id);
189 write(obj._request);
190 },
191 deserialize({ read }) {
192 return new ModuleExternalInitFragment(read(), read());
193 }
194 }
195);
196
197const generateModuleRemapping = (input, exportsInfo, runtime) => {
198 if (exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused) {
199 const properties = [];
200 for (const exportInfo of exportsInfo.orderedExports) {
201 const used = exportInfo.getUsedName(exportInfo.name, runtime);
202 if (!used) continue;
203 const nestedInfo = exportInfo.getNestedExportsInfo();
204 if (nestedInfo) {
205 const nestedExpr = generateModuleRemapping(
206 `${input}${propertyAccess([exportInfo.name])}`,
207 nestedInfo
208 );
209 if (nestedExpr) {
210 properties.push(`[${JSON.stringify(used)}]: y(${nestedExpr})`);
211 continue;
212 }
213 }
214 properties.push(
215 `[${JSON.stringify(used)}]: () => ${input}${propertyAccess([
216 exportInfo.name
217 ])}`
218 );
219 }
220 return `x({ ${properties.join(", ")} })`;
221 }
222};
223
224/**
225 * @param {string|number} id the module id
226 * @param {string|string[]} moduleAndSpecifiers the module request
227 * @param {ExportsInfo} exportsInfo exports info of this module
228 * @param {RuntimeSpec} runtime the runtime
229 * @returns {SourceData} the generated source
230 */
231const getSourceForModuleExternal = (
232 id,
233 moduleAndSpecifiers,
234 exportsInfo,
235 runtime
236) => {
237 if (!Array.isArray(moduleAndSpecifiers))
238 moduleAndSpecifiers = [moduleAndSpecifiers];
239 const initFragment = new ModuleExternalInitFragment(
240 id,
241 moduleAndSpecifiers[0]
242 );
243 const baseAccess = `${initFragment.getNamespaceIdentifier()}${propertyAccess(
244 moduleAndSpecifiers,
245 1
246 )}`;
247 const moduleRemapping = generateModuleRemapping(
248 baseAccess,
249 exportsInfo,
250 runtime
251 );
252 let expression = moduleRemapping || baseAccess;
253 return {
254 expression,
255 init: `var x = y => { var x = {}; ${RuntimeGlobals.definePropertyGetters}(x, y); return x; }\nvar y = x => () => x`,
256 runtimeRequirements: moduleRemapping
257 ? RUNTIME_REQUIREMENTS_FOR_MODULE
258 : undefined,
259 chunkInitFragments: [initFragment]
260 };
261};
262
263/**
264 * @param {string|string[]} urlAndGlobal the script request
265 * @param {RuntimeTemplate} runtimeTemplate the runtime template
266 * @returns {SourceData} the generated source
267 */
268const getSourceForScriptExternal = (urlAndGlobal, runtimeTemplate) => {
269 if (typeof urlAndGlobal === "string") {
270 urlAndGlobal = extractUrlAndGlobal(urlAndGlobal);
271 }
272 const url = urlAndGlobal[0];
273 const globalName = urlAndGlobal[1];
274 return {
275 init: "var __webpack_error__ = new Error();",
276 expression: `new Promise(${runtimeTemplate.basicFunction(
277 "resolve, reject",
278 [
279 `if(typeof ${globalName} !== "undefined") return resolve();`,
280 `${RuntimeGlobals.loadScript}(${JSON.stringify(
281 url
282 )}, ${runtimeTemplate.basicFunction("event", [
283 `if(typeof ${globalName} !== "undefined") return resolve();`,
284 "var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
285 "var realSrc = event && event.target && event.target.src;",
286 "__webpack_error__.message = 'Loading script failed.\\n(' + errorType + ': ' + realSrc + ')';",
287 "__webpack_error__.name = 'ScriptExternalLoadError';",
288 "__webpack_error__.type = errorType;",
289 "__webpack_error__.request = realSrc;",
290 "reject(__webpack_error__);"
291 ])}, ${JSON.stringify(globalName)});`
292 ]
293 )}).then(${runtimeTemplate.returningFunction(
294 `${globalName}${propertyAccess(urlAndGlobal, 2)}`
295 )})`,
296 runtimeRequirements: RUNTIME_REQUIREMENTS_FOR_SCRIPT
297 };
298};
299
300/**
301 * @param {string} variableName the variable name to check
302 * @param {string} request the request path
303 * @param {RuntimeTemplate} runtimeTemplate the runtime template
304 * @returns {string} the generated source
305 */
306const checkExternalVariable = (variableName, request, runtimeTemplate) => {
307 return `if(typeof ${variableName} === 'undefined') { ${runtimeTemplate.throwMissingModuleErrorBlock(
308 { request }
309 )} }\n`;
310};
311
312/**
313 * @param {string|number} id the module id
314 * @param {boolean} optional true, if the module is optional
315 * @param {string|string[]} request the request path
316 * @param {RuntimeTemplate} runtimeTemplate the runtime template
317 * @returns {SourceData} the generated source
318 */
319const getSourceForAmdOrUmdExternal = (
320 id,
321 optional,
322 request,
323 runtimeTemplate
324) => {
325 const externalVariable = `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
326 `${id}`
327 )}__`;
328 return {
329 init: optional
330 ? checkExternalVariable(
331 externalVariable,
332 Array.isArray(request) ? request.join(".") : request,
333 runtimeTemplate
334 )
335 : undefined,
336 expression: externalVariable
337 };
338};
339
340/**
341 * @param {boolean} optional true, if the module is optional
342 * @param {string|string[]} request the request path
343 * @param {RuntimeTemplate} runtimeTemplate the runtime template
344 * @returns {SourceData} the generated source
345 */
346const getSourceForDefaultCase = (optional, request, runtimeTemplate) => {
347 if (!Array.isArray(request)) {
348 // make it an array as the look up works the same basically
349 request = [request];
350 }
351
352 const variableName = request[0];
353 const objectLookup = propertyAccess(request, 1);
354 return {
355 init: optional
356 ? checkExternalVariable(variableName, request.join("."), runtimeTemplate)
357 : undefined,
358 expression: `${variableName}${objectLookup}`
359 };
360};
361
362class ExternalModule extends Module {
363 constructor(request, type, userRequest) {
364 super("javascript/dynamic", null);
365
366 // Info from Factory
367 /** @type {string | string[] | Record<string, string | string[]>} */
368 this.request = request;
369 /** @type {string} */
370 this.externalType = type;
371 /** @type {string} */
372 this.userRequest = userRequest;
373 }
374
375 /**
376 * @returns {Set<string>} types available (do not mutate)
377 */
378 getSourceTypes() {
379 return TYPES;
380 }
381
382 /**
383 * @param {LibIdentOptions} options options
384 * @returns {string | null} an identifier for library inclusion
385 */
386 libIdent(options) {
387 return this.userRequest;
388 }
389
390 /**
391 * @param {Chunk} chunk the chunk which condition should be checked
392 * @param {Compilation} compilation the compilation
393 * @returns {boolean} true, if the chunk is ok for the module
394 */
395 chunkCondition(chunk, { chunkGraph }) {
396 return chunkGraph.getNumberOfEntryModules(chunk) > 0;
397 }
398
399 /**
400 * @returns {string} a unique identifier of the module
401 */
402 identifier() {
403 return "external " + JSON.stringify(this.request);
404 }
405
406 /**
407 * @param {RequestShortener} requestShortener the request shortener
408 * @returns {string} a user readable identifier of the module
409 */
410 readableIdentifier(requestShortener) {
411 return "external " + JSON.stringify(this.request);
412 }
413
414 /**
415 * @param {NeedBuildContext} context context info
416 * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
417 * @returns {void}
418 */
419 needBuild(context, callback) {
420 return callback(null, !this.buildMeta);
421 }
422
423 /**
424 * @param {WebpackOptions} options webpack options
425 * @param {Compilation} compilation the compilation
426 * @param {ResolverWithOptions} resolver the resolver
427 * @param {InputFileSystem} fs the file system
428 * @param {function(WebpackError=): void} callback callback function
429 * @returns {void}
430 */
431 build(options, compilation, resolver, fs, callback) {
432 this.buildMeta = {
433 async: false,
434 exportsType: undefined
435 };
436 this.buildInfo = {
437 strict: true,
438 topLevelDeclarations: new Set(),
439 module: compilation.outputOptions.module
440 };
441 const { request, externalType } = this._getRequestAndExternalType();
442 this.buildMeta.exportsType = "dynamic";
443 let canMangle = false;
444 this.clearDependenciesAndBlocks();
445 switch (externalType) {
446 case "this":
447 this.buildInfo.strict = false;
448 break;
449 case "system":
450 if (!Array.isArray(request) || request.length === 1) {
451 this.buildMeta.exportsType = "namespace";
452 canMangle = true;
453 }
454 break;
455 case "module":
456 if (this.buildInfo.module) {
457 if (!Array.isArray(request) || request.length === 1) {
458 this.buildMeta.exportsType = "namespace";
459 canMangle = true;
460 }
461 } else {
462 this.buildMeta.async = true;
463 if (!Array.isArray(request) || request.length === 1) {
464 this.buildMeta.exportsType = "namespace";
465 canMangle = false;
466 }
467 }
468 break;
469 case "script":
470 case "promise":
471 this.buildMeta.async = true;
472 break;
473 case "import":
474 this.buildMeta.async = true;
475 if (!Array.isArray(request) || request.length === 1) {
476 this.buildMeta.exportsType = "namespace";
477 canMangle = false;
478 }
479 break;
480 }
481 this.addDependency(new StaticExportsDependency(true, canMangle));
482 callback();
483 }
484
485 /**
486 * @param {ConcatenationBailoutReasonContext} context context
487 * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
488 */
489 getConcatenationBailoutReason({ moduleGraph }) {
490 switch (this.externalType) {
491 case "amd":
492 case "amd-require":
493 case "umd":
494 case "umd2":
495 case "system":
496 case "jsonp":
497 return `${this.externalType} externals can't be concatenated`;
498 }
499 return undefined;
500 }
501
502 _getRequestAndExternalType() {
503 let { request, externalType } = this;
504 if (typeof request === "object" && !Array.isArray(request))
505 request = request[externalType];
506 return { request, externalType };
507 }
508
509 _getSourceData(runtimeTemplate, moduleGraph, chunkGraph, runtime) {
510 const { request, externalType } = this._getRequestAndExternalType();
511 switch (externalType) {
512 case "this":
513 case "window":
514 case "self":
515 return getSourceForGlobalVariableExternal(request, this.externalType);
516 case "global":
517 return getSourceForGlobalVariableExternal(
518 request,
519 runtimeTemplate.outputOptions.globalObject
520 );
521 case "commonjs":
522 case "commonjs2":
523 case "commonjs-module":
524 return getSourceForCommonJsExternal(request);
525 case "node-commonjs":
526 return this.buildInfo.module
527 ? getSourceForCommonJsExternalInNodeModule(request)
528 : getSourceForCommonJsExternal(request);
529 case "amd":
530 case "amd-require":
531 case "umd":
532 case "umd2":
533 case "system":
534 case "jsonp":
535 return getSourceForAmdOrUmdExternal(
536 chunkGraph.getModuleId(this),
537 this.isOptional(moduleGraph),
538 request,
539 runtimeTemplate
540 );
541 case "import":
542 return getSourceForImportExternal(request, runtimeTemplate);
543 case "script":
544 return getSourceForScriptExternal(request, runtimeTemplate);
545 case "module":
546 if (!this.buildInfo.module) {
547 if (!runtimeTemplate.supportsDynamicImport()) {
548 throw new Error(
549 "The target environment doesn't support dynamic import() syntax so it's not possible to use external type 'module' within a script" +
550 (runtimeTemplate.supportsEcmaScriptModuleSyntax()
551 ? "\nDid you mean to build a EcmaScript Module ('output.module: true')?"
552 : "")
553 );
554 }
555 return getSourceForImportExternal(request, runtimeTemplate);
556 }
557 if (!runtimeTemplate.supportsEcmaScriptModuleSyntax()) {
558 throw new Error(
559 "The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module'"
560 );
561 }
562 return getSourceForModuleExternal(
563 chunkGraph.getModuleId(this),
564 request,
565 moduleGraph.getExportsInfo(this),
566 runtime
567 );
568 case "var":
569 case "promise":
570 case "const":
571 case "let":
572 case "assign":
573 default:
574 return getSourceForDefaultCase(
575 this.isOptional(moduleGraph),
576 request,
577 runtimeTemplate
578 );
579 }
580 }
581
582 /**
583 * @param {CodeGenerationContext} context context for code generation
584 * @returns {CodeGenerationResult} result
585 */
586 codeGeneration({
587 runtimeTemplate,
588 moduleGraph,
589 chunkGraph,
590 runtime,
591 concatenationScope
592 }) {
593 const sourceData = this._getSourceData(
594 runtimeTemplate,
595 moduleGraph,
596 chunkGraph,
597 runtime
598 );
599
600 let sourceString = sourceData.expression;
601 if (sourceData.iife)
602 sourceString = `(function() { return ${sourceString}; }())`;
603 if (concatenationScope) {
604 sourceString = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${
605 ConcatenationScope.NAMESPACE_OBJECT_EXPORT
606 } = ${sourceString};`;
607 concatenationScope.registerNamespaceExport(
608 ConcatenationScope.NAMESPACE_OBJECT_EXPORT
609 );
610 } else {
611 sourceString = `module.exports = ${sourceString};`;
612 }
613 if (sourceData.init) sourceString = `${sourceData.init}\n${sourceString}`;
614
615 let data = undefined;
616 if (sourceData.chunkInitFragments) {
617 data = new Map();
618 data.set("chunkInitFragments", sourceData.chunkInitFragments);
619 }
620
621 const sources = new Map();
622 if (this.useSourceMap || this.useSimpleSourceMap) {
623 sources.set(
624 "javascript",
625 new OriginalSource(sourceString, this.identifier())
626 );
627 } else {
628 sources.set("javascript", new RawSource(sourceString));
629 }
630
631 let runtimeRequirements = sourceData.runtimeRequirements;
632 if (!concatenationScope) {
633 if (!runtimeRequirements) {
634 runtimeRequirements = RUNTIME_REQUIREMENTS;
635 } else {
636 const set = new Set(runtimeRequirements);
637 set.add(RuntimeGlobals.module);
638 runtimeRequirements = set;
639 }
640 }
641
642 return {
643 sources,
644 runtimeRequirements: runtimeRequirements || EMPTY_RUNTIME_REQUIREMENTS,
645 data
646 };
647 }
648
649 /**
650 * @param {string=} type the source type for which the size should be estimated
651 * @returns {number} the estimated size of the module (must be non-zero)
652 */
653 size(type) {
654 return 42;
655 }
656
657 /**
658 * @param {Hash} hash the hash used to track dependencies
659 * @param {UpdateHashContext} context context
660 * @returns {void}
661 */
662 updateHash(hash, context) {
663 const { chunkGraph } = context;
664 hash.update(this.externalType);
665 hash.update(JSON.stringify(this.request));
666 hash.update(
667 JSON.stringify(Boolean(this.isOptional(chunkGraph.moduleGraph)))
668 );
669 super.updateHash(hash, context);
670 }
671
672 serialize(context) {
673 const { write } = context;
674
675 write(this.request);
676 write(this.externalType);
677 write(this.userRequest);
678
679 super.serialize(context);
680 }
681
682 deserialize(context) {
683 const { read } = context;
684
685 this.request = read();
686 this.externalType = read();
687 this.userRequest = read();
688
689 super.deserialize(context);
690 }
691}
692
693makeSerializable(ExternalModule, "webpack/lib/ExternalModule");
694
695module.exports = ExternalModule;
Note: See TracBrowser for help on using the repository browser.