1 | /*
|
---|
2 | MIT License http://www.opensource.org/licenses/mit-license.php
|
---|
3 | Author Tobias Koppers @sokra
|
---|
4 | */
|
---|
5 |
|
---|
6 | "use strict";
|
---|
7 |
|
---|
8 | const Dependency = require("../Dependency");
|
---|
9 | const {
|
---|
10 | getDependencyUsedByExportsCondition
|
---|
11 | } = require("../optimize/InnerGraph");
|
---|
12 | const makeSerializable = require("../util/makeSerializable");
|
---|
13 | const propertyAccess = require("../util/propertyAccess");
|
---|
14 | const HarmonyImportDependency = require("./HarmonyImportDependency");
|
---|
15 |
|
---|
16 | /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
|
---|
17 | /** @typedef {import("../ChunkGraph")} ChunkGraph */
|
---|
18 | /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
|
---|
19 | /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */
|
---|
20 | /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
|
---|
21 | /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
|
---|
22 | /** @typedef {import("../ModuleGraph")} ModuleGraph */
|
---|
23 | /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
|
---|
24 | /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
|
---|
25 | /** @typedef {import("../WebpackError")} WebpackError */
|
---|
26 | /** @typedef {import("../util/Hash")} Hash */
|
---|
27 | /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
---|
28 |
|
---|
29 | const idsSymbol = Symbol("HarmonyImportSpecifierDependency.ids");
|
---|
30 |
|
---|
31 | class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
---|
32 | constructor(
|
---|
33 | request,
|
---|
34 | sourceOrder,
|
---|
35 | ids,
|
---|
36 | name,
|
---|
37 | range,
|
---|
38 | strictExportPresence,
|
---|
39 | assertions
|
---|
40 | ) {
|
---|
41 | super(request, sourceOrder, assertions);
|
---|
42 | this.ids = ids;
|
---|
43 | this.name = name;
|
---|
44 | this.range = range;
|
---|
45 | this.strictExportPresence = strictExportPresence;
|
---|
46 | this.namespaceObjectAsContext = false;
|
---|
47 | this.call = undefined;
|
---|
48 | this.directImport = undefined;
|
---|
49 | this.shorthand = undefined;
|
---|
50 | this.asiSafe = undefined;
|
---|
51 | /** @type {Set<string> | boolean} */
|
---|
52 | this.usedByExports = undefined;
|
---|
53 | }
|
---|
54 |
|
---|
55 | // TODO webpack 6 remove
|
---|
56 | get id() {
|
---|
57 | throw new Error("id was renamed to ids and type changed to string[]");
|
---|
58 | }
|
---|
59 |
|
---|
60 | // TODO webpack 6 remove
|
---|
61 | getId() {
|
---|
62 | throw new Error("id was renamed to ids and type changed to string[]");
|
---|
63 | }
|
---|
64 |
|
---|
65 | // TODO webpack 6 remove
|
---|
66 | setId() {
|
---|
67 | throw new Error("id was renamed to ids and type changed to string[]");
|
---|
68 | }
|
---|
69 |
|
---|
70 | get type() {
|
---|
71 | return "harmony import specifier";
|
---|
72 | }
|
---|
73 |
|
---|
74 | /**
|
---|
75 | * @param {ModuleGraph} moduleGraph the module graph
|
---|
76 | * @returns {string[]} the imported ids
|
---|
77 | */
|
---|
78 | getIds(moduleGraph) {
|
---|
79 | const meta = moduleGraph.getMetaIfExisting(this);
|
---|
80 | if (meta === undefined) return this.ids;
|
---|
81 | const ids = meta[idsSymbol];
|
---|
82 | return ids !== undefined ? ids : this.ids;
|
---|
83 | }
|
---|
84 |
|
---|
85 | /**
|
---|
86 | * @param {ModuleGraph} moduleGraph the module graph
|
---|
87 | * @param {string[]} ids the imported ids
|
---|
88 | * @returns {void}
|
---|
89 | */
|
---|
90 | setIds(moduleGraph, ids) {
|
---|
91 | moduleGraph.getMeta(this)[idsSymbol] = ids;
|
---|
92 | }
|
---|
93 |
|
---|
94 | /**
|
---|
95 | * @param {ModuleGraph} moduleGraph module graph
|
---|
96 | * @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
|
---|
97 | */
|
---|
98 | getCondition(moduleGraph) {
|
---|
99 | return getDependencyUsedByExportsCondition(
|
---|
100 | this,
|
---|
101 | this.usedByExports,
|
---|
102 | moduleGraph
|
---|
103 | );
|
---|
104 | }
|
---|
105 |
|
---|
106 | /**
|
---|
107 | * @param {ModuleGraph} moduleGraph the module graph
|
---|
108 | * @returns {ConnectionState} how this dependency connects the module to referencing modules
|
---|
109 | */
|
---|
110 | getModuleEvaluationSideEffectsState(moduleGraph) {
|
---|
111 | return false;
|
---|
112 | }
|
---|
113 |
|
---|
114 | /**
|
---|
115 | * Returns list of exports referenced by this dependency
|
---|
116 | * @param {ModuleGraph} moduleGraph module graph
|
---|
117 | * @param {RuntimeSpec} runtime the runtime for which the module is analysed
|
---|
118 | * @returns {(string[] | ReferencedExport)[]} referenced exports
|
---|
119 | */
|
---|
120 | getReferencedExports(moduleGraph, runtime) {
|
---|
121 | let ids = this.getIds(moduleGraph);
|
---|
122 | if (ids.length === 0) return Dependency.EXPORTS_OBJECT_REFERENCED;
|
---|
123 | let namespaceObjectAsContext = this.namespaceObjectAsContext;
|
---|
124 | if (ids[0] === "default") {
|
---|
125 | const selfModule = moduleGraph.getParentModule(this);
|
---|
126 | const importedModule = moduleGraph.getModule(this);
|
---|
127 | switch (
|
---|
128 | importedModule.getExportsType(
|
---|
129 | moduleGraph,
|
---|
130 | selfModule.buildMeta.strictHarmonyModule
|
---|
131 | )
|
---|
132 | ) {
|
---|
133 | case "default-only":
|
---|
134 | case "default-with-named":
|
---|
135 | if (ids.length === 1) return Dependency.EXPORTS_OBJECT_REFERENCED;
|
---|
136 | ids = ids.slice(1);
|
---|
137 | namespaceObjectAsContext = true;
|
---|
138 | break;
|
---|
139 | case "dynamic":
|
---|
140 | return Dependency.EXPORTS_OBJECT_REFERENCED;
|
---|
141 | }
|
---|
142 | }
|
---|
143 |
|
---|
144 | if (
|
---|
145 | this.call &&
|
---|
146 | !this.directImport &&
|
---|
147 | (namespaceObjectAsContext || ids.length > 1)
|
---|
148 | ) {
|
---|
149 | if (ids.length === 1) return Dependency.EXPORTS_OBJECT_REFERENCED;
|
---|
150 | ids = ids.slice(0, -1);
|
---|
151 | }
|
---|
152 |
|
---|
153 | return [ids];
|
---|
154 | }
|
---|
155 |
|
---|
156 | /**
|
---|
157 | * Returns warnings
|
---|
158 | * @param {ModuleGraph} moduleGraph module graph
|
---|
159 | * @returns {WebpackError[]} warnings
|
---|
160 | */
|
---|
161 | getWarnings(moduleGraph) {
|
---|
162 | if (
|
---|
163 | this.strictExportPresence ||
|
---|
164 | moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
|
---|
165 | ) {
|
---|
166 | return null;
|
---|
167 | }
|
---|
168 | return this._getErrors(moduleGraph);
|
---|
169 | }
|
---|
170 |
|
---|
171 | /**
|
---|
172 | * Returns errors
|
---|
173 | * @param {ModuleGraph} moduleGraph module graph
|
---|
174 | * @returns {WebpackError[]} errors
|
---|
175 | */
|
---|
176 | getErrors(moduleGraph) {
|
---|
177 | if (
|
---|
178 | this.strictExportPresence ||
|
---|
179 | moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
|
---|
180 | ) {
|
---|
181 | return this._getErrors(moduleGraph);
|
---|
182 | }
|
---|
183 | return null;
|
---|
184 | }
|
---|
185 |
|
---|
186 | /**
|
---|
187 | * @param {ModuleGraph} moduleGraph module graph
|
---|
188 | * @returns {WebpackError[] | undefined} errors
|
---|
189 | */
|
---|
190 | _getErrors(moduleGraph) {
|
---|
191 | const ids = this.getIds(moduleGraph);
|
---|
192 | return this.getLinkingErrors(
|
---|
193 | moduleGraph,
|
---|
194 | ids,
|
---|
195 | `(imported as '${this.name}')`
|
---|
196 | );
|
---|
197 | }
|
---|
198 |
|
---|
199 | /**
|
---|
200 | * implement this method to allow the occurrence order plugin to count correctly
|
---|
201 | * @returns {number} count how often the id is used in this dependency
|
---|
202 | */
|
---|
203 | getNumberOfIdOccurrences() {
|
---|
204 | return 0;
|
---|
205 | }
|
---|
206 |
|
---|
207 | serialize(context) {
|
---|
208 | const { write } = context;
|
---|
209 | write(this.ids);
|
---|
210 | write(this.name);
|
---|
211 | write(this.range);
|
---|
212 | write(this.strictExportPresence);
|
---|
213 | write(this.namespaceObjectAsContext);
|
---|
214 | write(this.call);
|
---|
215 | write(this.directImport);
|
---|
216 | write(this.shorthand);
|
---|
217 | write(this.asiSafe);
|
---|
218 | write(this.usedByExports);
|
---|
219 | super.serialize(context);
|
---|
220 | }
|
---|
221 |
|
---|
222 | deserialize(context) {
|
---|
223 | const { read } = context;
|
---|
224 | this.ids = read();
|
---|
225 | this.name = read();
|
---|
226 | this.range = read();
|
---|
227 | this.strictExportPresence = read();
|
---|
228 | this.namespaceObjectAsContext = read();
|
---|
229 | this.call = read();
|
---|
230 | this.directImport = read();
|
---|
231 | this.shorthand = read();
|
---|
232 | this.asiSafe = read();
|
---|
233 | this.usedByExports = read();
|
---|
234 | super.deserialize(context);
|
---|
235 | }
|
---|
236 | }
|
---|
237 |
|
---|
238 | makeSerializable(
|
---|
239 | HarmonyImportSpecifierDependency,
|
---|
240 | "webpack/lib/dependencies/HarmonyImportSpecifierDependency"
|
---|
241 | );
|
---|
242 |
|
---|
243 | HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependencyTemplate extends (
|
---|
244 | HarmonyImportDependency.Template
|
---|
245 | ) {
|
---|
246 | /**
|
---|
247 | * @param {Dependency} dependency the dependency for which the template should be applied
|
---|
248 | * @param {ReplaceSource} source the current replace source which can be modified
|
---|
249 | * @param {DependencyTemplateContext} templateContext the context object
|
---|
250 | * @returns {void}
|
---|
251 | */
|
---|
252 | apply(dependency, source, templateContext) {
|
---|
253 | const dep = /** @type {HarmonyImportSpecifierDependency} */ (dependency);
|
---|
254 | const { moduleGraph, module, runtime, concatenationScope } =
|
---|
255 | templateContext;
|
---|
256 | const connection = moduleGraph.getConnection(dep);
|
---|
257 | // Skip rendering depending when dependency is conditional
|
---|
258 | if (connection && !connection.isTargetActive(runtime)) return;
|
---|
259 |
|
---|
260 | const ids = dep.getIds(moduleGraph);
|
---|
261 |
|
---|
262 | let exportExpr;
|
---|
263 | if (
|
---|
264 | connection &&
|
---|
265 | concatenationScope &&
|
---|
266 | concatenationScope.isModuleInScope(connection.module)
|
---|
267 | ) {
|
---|
268 | if (ids.length === 0) {
|
---|
269 | exportExpr = concatenationScope.createModuleReference(
|
---|
270 | connection.module,
|
---|
271 | {
|
---|
272 | asiSafe: dep.asiSafe
|
---|
273 | }
|
---|
274 | );
|
---|
275 | } else if (dep.namespaceObjectAsContext && ids.length === 1) {
|
---|
276 | exportExpr =
|
---|
277 | concatenationScope.createModuleReference(connection.module, {
|
---|
278 | asiSafe: dep.asiSafe
|
---|
279 | }) + propertyAccess(ids);
|
---|
280 | } else {
|
---|
281 | exportExpr = concatenationScope.createModuleReference(
|
---|
282 | connection.module,
|
---|
283 | {
|
---|
284 | ids,
|
---|
285 | call: dep.call,
|
---|
286 | directImport: dep.directImport,
|
---|
287 | asiSafe: dep.asiSafe
|
---|
288 | }
|
---|
289 | );
|
---|
290 | }
|
---|
291 | } else {
|
---|
292 | super.apply(dependency, source, templateContext);
|
---|
293 |
|
---|
294 | const { runtimeTemplate, initFragments, runtimeRequirements } =
|
---|
295 | templateContext;
|
---|
296 |
|
---|
297 | exportExpr = runtimeTemplate.exportFromImport({
|
---|
298 | moduleGraph,
|
---|
299 | module: moduleGraph.getModule(dep),
|
---|
300 | request: dep.request,
|
---|
301 | exportName: ids,
|
---|
302 | originModule: module,
|
---|
303 | asiSafe: dep.shorthand ? true : dep.asiSafe,
|
---|
304 | isCall: dep.call,
|
---|
305 | callContext: !dep.directImport,
|
---|
306 | defaultInterop: true,
|
---|
307 | importVar: dep.getImportVar(moduleGraph),
|
---|
308 | initFragments,
|
---|
309 | runtime,
|
---|
310 | runtimeRequirements
|
---|
311 | });
|
---|
312 | }
|
---|
313 | if (dep.shorthand) {
|
---|
314 | source.insert(dep.range[1], `: ${exportExpr}`);
|
---|
315 | } else {
|
---|
316 | source.replace(dep.range[0], dep.range[1] - 1, exportExpr);
|
---|
317 | }
|
---|
318 | }
|
---|
319 | };
|
---|
320 |
|
---|
321 | module.exports = HarmonyImportSpecifierDependency;
|
---|