1
|
/*
|
2
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
3
|
Author Tobias Koppers @sokra
|
4
|
*/
|
5
|
"use strict";
|
6
|
|
7
|
const Template = require("./Template");
|
8
|
|
9
|
/** @typedef {import("./Module")} Module */
|
10
|
|
11
|
module.exports = class RuntimeTemplate {
|
12
|
constructor(outputOptions, requestShortener) {
|
13
|
this.outputOptions = outputOptions || {};
|
14
|
this.requestShortener = requestShortener;
|
15
|
}
|
16
|
|
17
|
/**
|
18
|
* Add a comment
|
19
|
* @param {object} options Information content of the comment
|
20
|
* @param {string=} options.request request string used originally
|
21
|
* @param {string=} options.chunkName name of the chunk referenced
|
22
|
* @param {string=} options.chunkReason reason information of the chunk
|
23
|
* @param {string=} options.message additional message
|
24
|
* @param {string=} options.exportName name of the export
|
25
|
* @returns {string} comment
|
26
|
*/
|
27
|
comment({ request, chunkName, chunkReason, message, exportName }) {
|
28
|
let content;
|
29
|
if (this.outputOptions.pathinfo) {
|
30
|
content = [message, request, chunkName, chunkReason]
|
31
|
.filter(Boolean)
|
32
|
.map(item => this.requestShortener.shorten(item))
|
33
|
.join(" | ");
|
34
|
} else {
|
35
|
content = [message, chunkName, chunkReason]
|
36
|
.filter(Boolean)
|
37
|
.map(item => this.requestShortener.shorten(item))
|
38
|
.join(" | ");
|
39
|
}
|
40
|
if (!content) return "";
|
41
|
if (this.outputOptions.pathinfo) {
|
42
|
return Template.toComment(content) + " ";
|
43
|
} else {
|
44
|
return Template.toNormalComment(content) + " ";
|
45
|
}
|
46
|
}
|
47
|
|
48
|
throwMissingModuleErrorFunction({ request }) {
|
49
|
const err = `Cannot find module '${request}'`;
|
50
|
return `function webpackMissingModule() { var e = new Error(${JSON.stringify(
|
51
|
err
|
52
|
)}); e.code = 'MODULE_NOT_FOUND'; throw e; }`;
|
53
|
}
|
54
|
|
55
|
missingModule({ request }) {
|
56
|
return `!(${this.throwMissingModuleErrorFunction({ request })}())`;
|
57
|
}
|
58
|
|
59
|
missingModuleStatement({ request }) {
|
60
|
return `${this.missingModule({ request })};\n`;
|
61
|
}
|
62
|
|
63
|
missingModulePromise({ request }) {
|
64
|
return `Promise.resolve().then(${this.throwMissingModuleErrorFunction({
|
65
|
request
|
66
|
})})`;
|
67
|
}
|
68
|
|
69
|
moduleId({ module, request }) {
|
70
|
if (!module) {
|
71
|
return this.missingModule({
|
72
|
request
|
73
|
});
|
74
|
}
|
75
|
if (module.id === null) {
|
76
|
throw new Error(
|
77
|
`RuntimeTemplate.moduleId(): Module ${module.identifier()} has no id. This should not happen.`
|
78
|
);
|
79
|
}
|
80
|
return `${this.comment({ request })}${JSON.stringify(module.id)}`;
|
81
|
}
|
82
|
|
83
|
moduleRaw({ module, request }) {
|
84
|
if (!module) {
|
85
|
return this.missingModule({
|
86
|
request
|
87
|
});
|
88
|
}
|
89
|
return `__webpack_require__(${this.moduleId({ module, request })})`;
|
90
|
}
|
91
|
|
92
|
moduleExports({ module, request }) {
|
93
|
return this.moduleRaw({
|
94
|
module,
|
95
|
request
|
96
|
});
|
97
|
}
|
98
|
|
99
|
moduleNamespace({ module, request, strict }) {
|
100
|
if (!module) {
|
101
|
return this.missingModule({
|
102
|
request
|
103
|
});
|
104
|
}
|
105
|
const moduleId = this.moduleId({
|
106
|
module,
|
107
|
request
|
108
|
});
|
109
|
const exportsType = module.buildMeta && module.buildMeta.exportsType;
|
110
|
if (exportsType === "namespace") {
|
111
|
const rawModule = this.moduleRaw({
|
112
|
module,
|
113
|
request
|
114
|
});
|
115
|
return rawModule;
|
116
|
} else if (exportsType === "named") {
|
117
|
return `__webpack_require__.t(${moduleId}, 3)`;
|
118
|
} else if (strict) {
|
119
|
return `__webpack_require__.t(${moduleId}, 1)`;
|
120
|
} else {
|
121
|
return `__webpack_require__.t(${moduleId}, 7)`;
|
122
|
}
|
123
|
}
|
124
|
|
125
|
moduleNamespacePromise({ block, module, request, message, strict, weak }) {
|
126
|
if (!module) {
|
127
|
return this.missingModulePromise({
|
128
|
request
|
129
|
});
|
130
|
}
|
131
|
if (module.id === null) {
|
132
|
throw new Error(
|
133
|
`RuntimeTemplate.moduleNamespacePromise(): Module ${module.identifier()} has no id. This should not happen.`
|
134
|
);
|
135
|
}
|
136
|
const promise = this.blockPromise({
|
137
|
block,
|
138
|
message
|
139
|
});
|
140
|
|
141
|
let getModuleFunction;
|
142
|
let idExpr = JSON.stringify(module.id);
|
143
|
const comment = this.comment({
|
144
|
request
|
145
|
});
|
146
|
let header = "";
|
147
|
if (weak) {
|
148
|
if (idExpr.length > 8) {
|
149
|
// 'var x="nnnnnn";x,"+x+",x' vs '"nnnnnn",nnnnnn,"nnnnnn"'
|
150
|
header += `var id = ${idExpr}; `;
|
151
|
idExpr = "id";
|
152
|
}
|
153
|
header += `if(!__webpack_require__.m[${idExpr}]) { var e = new Error("Module '" + ${idExpr} + "' is not available (weak dependency)"); e.code = 'MODULE_NOT_FOUND'; throw e; } `;
|
154
|
}
|
155
|
const moduleId = this.moduleId({
|
156
|
module,
|
157
|
request
|
158
|
});
|
159
|
const exportsType = module.buildMeta && module.buildMeta.exportsType;
|
160
|
if (exportsType === "namespace") {
|
161
|
if (header) {
|
162
|
const rawModule = this.moduleRaw({
|
163
|
module,
|
164
|
request
|
165
|
});
|
166
|
getModuleFunction = `function() { ${header}return ${rawModule}; }`;
|
167
|
} else {
|
168
|
getModuleFunction = `__webpack_require__.bind(null, ${comment}${idExpr})`;
|
169
|
}
|
170
|
} else if (exportsType === "named") {
|
171
|
if (header) {
|
172
|
getModuleFunction = `function() { ${header}return __webpack_require__.t(${moduleId}, 3); }`;
|
173
|
} else {
|
174
|
getModuleFunction = `__webpack_require__.t.bind(null, ${comment}${idExpr}, 3)`;
|
175
|
}
|
176
|
} else if (strict) {
|
177
|
if (header) {
|
178
|
getModuleFunction = `function() { ${header}return __webpack_require__.t(${moduleId}, 1); }`;
|
179
|
} else {
|
180
|
getModuleFunction = `__webpack_require__.t.bind(null, ${comment}${idExpr}, 1)`;
|
181
|
}
|
182
|
} else {
|
183
|
if (header) {
|
184
|
getModuleFunction = `function() { ${header}return __webpack_require__.t(${moduleId}, 7); }`;
|
185
|
} else {
|
186
|
getModuleFunction = `__webpack_require__.t.bind(null, ${comment}${idExpr}, 7)`;
|
187
|
}
|
188
|
}
|
189
|
|
190
|
return `${promise || "Promise.resolve()"}.then(${getModuleFunction})`;
|
191
|
}
|
192
|
|
193
|
/**
|
194
|
*
|
195
|
* @param {Object} options options object
|
196
|
* @param {boolean=} options.update whether a new variable should be created or the existing one updated
|
197
|
* @param {Module} options.module the module
|
198
|
* @param {string} options.request the request that should be printed as comment
|
199
|
* @param {string} options.importVar name of the import variable
|
200
|
* @param {Module} options.originModule module in which the statement is emitted
|
201
|
* @returns {string} the import statement
|
202
|
*/
|
203
|
importStatement({ update, module, request, importVar, originModule }) {
|
204
|
if (!module) {
|
205
|
return this.missingModuleStatement({
|
206
|
request
|
207
|
});
|
208
|
}
|
209
|
const moduleId = this.moduleId({
|
210
|
module,
|
211
|
request
|
212
|
});
|
213
|
const optDeclaration = update ? "" : "var ";
|
214
|
|
215
|
const exportsType = module.buildMeta && module.buildMeta.exportsType;
|
216
|
let content = `/* harmony import */ ${optDeclaration}${importVar} = __webpack_require__(${moduleId});\n`;
|
217
|
|
218
|
if (!exportsType && !originModule.buildMeta.strictHarmonyModule) {
|
219
|
content += `/* harmony import */ ${optDeclaration}${importVar}_default = /*#__PURE__*/__webpack_require__.n(${importVar});\n`;
|
220
|
}
|
221
|
if (exportsType === "named") {
|
222
|
if (Array.isArray(module.buildMeta.providedExports)) {
|
223
|
content += `${optDeclaration}${importVar}_namespace = /*#__PURE__*/__webpack_require__.t(${moduleId}, 1);\n`;
|
224
|
} else {
|
225
|
content += `${optDeclaration}${importVar}_namespace = /*#__PURE__*/__webpack_require__.t(${moduleId});\n`;
|
226
|
}
|
227
|
}
|
228
|
return content;
|
229
|
}
|
230
|
|
231
|
exportFromImport({
|
232
|
module,
|
233
|
request,
|
234
|
exportName,
|
235
|
originModule,
|
236
|
asiSafe,
|
237
|
isCall,
|
238
|
callContext,
|
239
|
importVar
|
240
|
}) {
|
241
|
if (!module) {
|
242
|
return this.missingModule({
|
243
|
request
|
244
|
});
|
245
|
}
|
246
|
const exportsType = module.buildMeta && module.buildMeta.exportsType;
|
247
|
|
248
|
if (!exportsType) {
|
249
|
if (exportName === "default") {
|
250
|
if (!originModule.buildMeta.strictHarmonyModule) {
|
251
|
if (isCall) {
|
252
|
return `${importVar}_default()`;
|
253
|
} else if (asiSafe) {
|
254
|
return `(${importVar}_default())`;
|
255
|
} else {
|
256
|
return `${importVar}_default.a`;
|
257
|
}
|
258
|
} else {
|
259
|
return importVar;
|
260
|
}
|
261
|
} else if (originModule.buildMeta.strictHarmonyModule) {
|
262
|
if (exportName) {
|
263
|
return "/* non-default import from non-esm module */undefined";
|
264
|
} else {
|
265
|
return `/*#__PURE__*/__webpack_require__.t(${importVar})`;
|
266
|
}
|
267
|
}
|
268
|
}
|
269
|
|
270
|
if (exportsType === "named") {
|
271
|
if (exportName === "default") {
|
272
|
return importVar;
|
273
|
} else if (!exportName) {
|
274
|
return `${importVar}_namespace`;
|
275
|
}
|
276
|
}
|
277
|
|
278
|
if (exportName) {
|
279
|
const used = module.isUsed(exportName);
|
280
|
if (!used) {
|
281
|
const comment = Template.toNormalComment(`unused export ${exportName}`);
|
282
|
return `${comment} undefined`;
|
283
|
}
|
284
|
const comment =
|
285
|
used !== exportName ? Template.toNormalComment(exportName) + " " : "";
|
286
|
const access = `${importVar}[${comment}${JSON.stringify(used)}]`;
|
287
|
if (isCall) {
|
288
|
if (callContext === false && asiSafe) {
|
289
|
return `(0,${access})`;
|
290
|
} else if (callContext === false) {
|
291
|
return `Object(${access})`;
|
292
|
}
|
293
|
}
|
294
|
return access;
|
295
|
} else {
|
296
|
return importVar;
|
297
|
}
|
298
|
}
|
299
|
|
300
|
blockPromise({ block, message }) {
|
301
|
if (!block || !block.chunkGroup || block.chunkGroup.chunks.length === 0) {
|
302
|
const comment = this.comment({
|
303
|
message
|
304
|
});
|
305
|
return `Promise.resolve(${comment.trim()})`;
|
306
|
}
|
307
|
const chunks = block.chunkGroup.chunks.filter(
|
308
|
chunk => !chunk.hasRuntime() && chunk.id !== null
|
309
|
);
|
310
|
const comment = this.comment({
|
311
|
message,
|
312
|
chunkName: block.chunkName,
|
313
|
chunkReason: block.chunkReason
|
314
|
});
|
315
|
if (chunks.length === 1) {
|
316
|
const chunkId = JSON.stringify(chunks[0].id);
|
317
|
return `__webpack_require__.e(${comment}${chunkId})`;
|
318
|
} else if (chunks.length > 0) {
|
319
|
const requireChunkId = chunk =>
|
320
|
`__webpack_require__.e(${JSON.stringify(chunk.id)})`;
|
321
|
return `Promise.all(${comment.trim()}[${chunks
|
322
|
.map(requireChunkId)
|
323
|
.join(", ")}])`;
|
324
|
} else {
|
325
|
return `Promise.resolve(${comment.trim()})`;
|
326
|
}
|
327
|
}
|
328
|
|
329
|
onError() {
|
330
|
return "__webpack_require__.oe";
|
331
|
}
|
332
|
|
333
|
defineEsModuleFlagStatement({ exportsArgument }) {
|
334
|
return `__webpack_require__.r(${exportsArgument});\n`;
|
335
|
}
|
336
|
};
|