source: imaps-frontend/node_modules/webpack/lib/dependencies/HarmonyImportDependency.js

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

F4 Finalna Verzija

  • Property mode set to 100644
File size: 11.7 KB
RevLine 
[79a0317]1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const ConditionalInitFragment = require("../ConditionalInitFragment");
9const Dependency = require("../Dependency");
10const HarmonyLinkingError = require("../HarmonyLinkingError");
11const InitFragment = require("../InitFragment");
12const Template = require("../Template");
13const AwaitDependenciesInitFragment = require("../async-modules/AwaitDependenciesInitFragment");
14const { filterRuntime, mergeRuntime } = require("../util/runtime");
15const ModuleDependency = require("./ModuleDependency");
16
17/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
18/** @typedef {import("webpack-sources").Source} Source */
19/** @typedef {import("../ChunkGraph")} ChunkGraph */
20/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */
21/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
22/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
23/** @typedef {import("../ExportsInfo")} ExportsInfo */
24/** @typedef {import("../Module")} Module */
25/** @typedef {import("../Module").BuildMeta} BuildMeta */
26/** @typedef {import("../ModuleGraph")} ModuleGraph */
27/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
28/** @typedef {import("../WebpackError")} WebpackError */
29/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
30/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
31/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
32/** @typedef {import("../util/Hash")} Hash */
33/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
34
35const ExportPresenceModes = {
36 NONE: /** @type {0} */ (0),
37 WARN: /** @type {1} */ (1),
38 AUTO: /** @type {2} */ (2),
39 ERROR: /** @type {3} */ (3),
40 /**
41 * @param {string | false} str param
42 * @returns {0 | 1 | 2 | 3} result
43 */
44 fromUserOption(str) {
45 switch (str) {
46 case "error":
47 return ExportPresenceModes.ERROR;
48 case "warn":
49 return ExportPresenceModes.WARN;
50 case "auto":
51 return ExportPresenceModes.AUTO;
52 case false:
53 return ExportPresenceModes.NONE;
54 default:
55 throw new Error(`Invalid export presence value ${str}`);
56 }
57 }
58};
59
60class HarmonyImportDependency extends ModuleDependency {
61 /**
62 * @param {string} request request string
63 * @param {number} sourceOrder source order
64 * @param {ImportAttributes=} attributes import attributes
65 */
66 constructor(request, sourceOrder, attributes) {
67 super(request);
68 this.sourceOrder = sourceOrder;
69 this.assertions = attributes;
70 }
71
72 get category() {
73 return "esm";
74 }
75
76 /**
77 * Returns list of exports referenced by this dependency
78 * @param {ModuleGraph} moduleGraph module graph
79 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
80 * @returns {(string[] | ReferencedExport)[]} referenced exports
81 */
82 getReferencedExports(moduleGraph, runtime) {
83 return Dependency.NO_EXPORTS_REFERENCED;
84 }
85
86 /**
87 * @param {ModuleGraph} moduleGraph the module graph
88 * @returns {string} name of the variable for the import
89 */
90 getImportVar(moduleGraph) {
91 const module = /** @type {Module} */ (moduleGraph.getParentModule(this));
92 const meta = /** @type {TODO} */ (moduleGraph.getMeta(module));
93 let importVarMap = meta.importVarMap;
94 if (!importVarMap) meta.importVarMap = importVarMap = new Map();
95 let importVar = importVarMap.get(
96 /** @type {Module} */ (moduleGraph.getModule(this))
97 );
98 if (importVar) return importVar;
99 importVar = `${Template.toIdentifier(
100 `${this.userRequest}`
101 )}__WEBPACK_IMPORTED_MODULE_${importVarMap.size}__`;
102 importVarMap.set(
103 /** @type {Module} */ (moduleGraph.getModule(this)),
104 importVar
105 );
106 return importVar;
107 }
108
109 /**
110 * @param {boolean} update create new variables or update existing one
111 * @param {DependencyTemplateContext} templateContext the template context
112 * @returns {[string, string]} the import statement and the compat statement
113 */
114 getImportStatement(
115 update,
116 { runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements }
117 ) {
118 return runtimeTemplate.importStatement({
119 update,
120 module: /** @type {Module} */ (moduleGraph.getModule(this)),
121 chunkGraph,
122 importVar: this.getImportVar(moduleGraph),
123 request: this.request,
124 originModule: module,
125 runtimeRequirements
126 });
127 }
128
129 /**
130 * @param {ModuleGraph} moduleGraph module graph
131 * @param {string[]} ids imported ids
132 * @param {string} additionalMessage extra info included in the error message
133 * @returns {WebpackError[] | undefined} errors
134 */
135 getLinkingErrors(moduleGraph, ids, additionalMessage) {
136 const importedModule = moduleGraph.getModule(this);
137 // ignore errors for missing or failed modules
138 if (!importedModule || importedModule.getNumberOfErrors() > 0) {
139 return;
140 }
141
142 const parentModule =
143 /** @type {Module} */
144 (moduleGraph.getParentModule(this));
145 const exportsType = importedModule.getExportsType(
146 moduleGraph,
147 /** @type {BuildMeta} */ (parentModule.buildMeta).strictHarmonyModule
148 );
149 if (exportsType === "namespace" || exportsType === "default-with-named") {
150 if (ids.length === 0) {
151 return;
152 }
153
154 if (
155 (exportsType !== "default-with-named" || ids[0] !== "default") &&
156 moduleGraph.isExportProvided(importedModule, ids) === false
157 ) {
158 // We are sure that it's not provided
159
160 // Try to provide detailed info in the error message
161 let pos = 0;
162 let exportsInfo = moduleGraph.getExportsInfo(importedModule);
163 while (pos < ids.length && exportsInfo) {
164 const id = ids[pos++];
165 const exportInfo = exportsInfo.getReadOnlyExportInfo(id);
166 if (exportInfo.provided === false) {
167 // We are sure that it's not provided
168 const providedExports = exportsInfo.getProvidedExports();
169 const moreInfo = !Array.isArray(providedExports)
170 ? " (possible exports unknown)"
171 : providedExports.length === 0
172 ? " (module has no exports)"
173 : ` (possible exports: ${providedExports.join(", ")})`;
174 return [
175 new HarmonyLinkingError(
176 `export ${ids
177 .slice(0, pos)
178 .map(id => `'${id}'`)
179 .join(".")} ${additionalMessage} was not found in '${
180 this.userRequest
181 }'${moreInfo}`
182 )
183 ];
184 }
185 exportsInfo =
186 /** @type {ExportsInfo} */
187 (exportInfo.getNestedExportsInfo());
188 }
189
190 // General error message
191 return [
192 new HarmonyLinkingError(
193 `export ${ids
194 .map(id => `'${id}'`)
195 .join(".")} ${additionalMessage} was not found in '${
196 this.userRequest
197 }'`
198 )
199 ];
200 }
201 }
202 switch (exportsType) {
203 case "default-only":
204 // It's has only a default export
205 if (ids.length > 0 && ids[0] !== "default") {
206 // In strict harmony modules we only support the default export
207 return [
208 new HarmonyLinkingError(
209 `Can't import the named export ${ids
210 .map(id => `'${id}'`)
211 .join(
212 "."
213 )} ${additionalMessage} from default-exporting module (only default export is available)`
214 )
215 ];
216 }
217 break;
218 case "default-with-named":
219 // It has a default export and named properties redirect
220 // In some cases we still want to warn here
221 if (
222 ids.length > 0 &&
223 ids[0] !== "default" &&
224 /** @type {BuildMeta} */
225 (importedModule.buildMeta).defaultObject === "redirect-warn"
226 ) {
227 // For these modules only the default export is supported
228 return [
229 new HarmonyLinkingError(
230 `Should not import the named export ${ids
231 .map(id => `'${id}'`)
232 .join(
233 "."
234 )} ${additionalMessage} from default-exporting module (only default export is available soon)`
235 )
236 ];
237 }
238 break;
239 }
240 }
241
242 /**
243 * @param {ObjectSerializerContext} context context
244 */
245 serialize(context) {
246 const { write } = context;
247 write(this.sourceOrder);
248 write(this.assertions);
249 super.serialize(context);
250 }
251
252 /**
253 * @param {ObjectDeserializerContext} context context
254 */
255 deserialize(context) {
256 const { read } = context;
257 this.sourceOrder = read();
258 this.assertions = read();
259 super.deserialize(context);
260 }
261}
262
263module.exports = HarmonyImportDependency;
264
265/** @type {WeakMap<Module, WeakMap<Module, RuntimeSpec | boolean>>} */
266const importEmittedMap = new WeakMap();
267
268HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends (
269 ModuleDependency.Template
270) {
271 /**
272 * @param {Dependency} dependency the dependency for which the template should be applied
273 * @param {ReplaceSource} source the current replace source which can be modified
274 * @param {DependencyTemplateContext} templateContext the context object
275 * @returns {void}
276 */
277 apply(dependency, source, templateContext) {
278 const dep = /** @type {HarmonyImportDependency} */ (dependency);
279 const { module, chunkGraph, moduleGraph, runtime } = templateContext;
280
281 const connection = moduleGraph.getConnection(dep);
282 if (connection && !connection.isTargetActive(runtime)) return;
283
284 const referencedModule = connection && connection.module;
285
286 if (
287 connection &&
288 connection.weak &&
289 referencedModule &&
290 chunkGraph.getModuleId(referencedModule) === null
291 ) {
292 // in weak references, module might not be in any chunk
293 // but that's ok, we don't need that logic in this case
294 return;
295 }
296
297 const moduleKey = referencedModule
298 ? referencedModule.identifier()
299 : dep.request;
300 const key = `harmony import ${moduleKey}`;
301
302 const runtimeCondition = dep.weak
303 ? false
304 : connection
305 ? filterRuntime(runtime, r => connection.isTargetActive(r))
306 : true;
307
308 if (module && referencedModule) {
309 let emittedModules = importEmittedMap.get(module);
310 if (emittedModules === undefined) {
311 emittedModules = new WeakMap();
312 importEmittedMap.set(module, emittedModules);
313 }
314 let mergedRuntimeCondition = runtimeCondition;
315 const oldRuntimeCondition = emittedModules.get(referencedModule) || false;
316 if (oldRuntimeCondition !== false && mergedRuntimeCondition !== true) {
317 if (mergedRuntimeCondition === false || oldRuntimeCondition === true) {
318 mergedRuntimeCondition = oldRuntimeCondition;
319 } else {
320 mergedRuntimeCondition = mergeRuntime(
321 oldRuntimeCondition,
322 mergedRuntimeCondition
323 );
324 }
325 }
326 emittedModules.set(referencedModule, mergedRuntimeCondition);
327 }
328
329 const importStatement = dep.getImportStatement(false, templateContext);
330 if (
331 referencedModule &&
332 templateContext.moduleGraph.isAsync(referencedModule)
333 ) {
334 templateContext.initFragments.push(
335 new ConditionalInitFragment(
336 importStatement[0],
337 InitFragment.STAGE_HARMONY_IMPORTS,
338 dep.sourceOrder,
339 key,
340 runtimeCondition
341 )
342 );
343 templateContext.initFragments.push(
344 new AwaitDependenciesInitFragment(
345 new Set([dep.getImportVar(templateContext.moduleGraph)])
346 )
347 );
348 templateContext.initFragments.push(
349 new ConditionalInitFragment(
350 importStatement[1],
351 InitFragment.STAGE_ASYNC_HARMONY_IMPORTS,
352 dep.sourceOrder,
353 `${key} compat`,
354 runtimeCondition
355 )
356 );
357 } else {
358 templateContext.initFragments.push(
359 new ConditionalInitFragment(
360 importStatement[0] + importStatement[1],
361 InitFragment.STAGE_HARMONY_IMPORTS,
362 dep.sourceOrder,
363 key,
364 runtimeCondition
365 )
366 );
367 }
368 }
369
370 /**
371 * @param {Module} module the module
372 * @param {Module} referencedModule the referenced module
373 * @returns {RuntimeSpec | boolean} runtimeCondition in which this import has been emitted
374 */
375 static getImportEmittedRuntime(module, referencedModule) {
376 const emittedModules = importEmittedMap.get(module);
377 if (emittedModules === undefined) return false;
378 return emittedModules.get(referencedModule) || false;
379 }
380};
381
382module.exports.ExportPresenceModes = ExportPresenceModes;
Note: See TracBrowser for help on using the repository browser.