webpack 4.8.2 → 4.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -52
- package/bin/webpack.js +128 -43
- package/lib/AmdMainTemplatePlugin.js +10 -0
- package/lib/AsyncDependencyToInitialChunkError.js +12 -2
- package/lib/BannerPlugin.js +115 -101
- package/lib/CaseSensitiveModulesWarning.js +20 -2
- package/lib/Chunk.js +1 -0
- package/lib/ChunkGroup.js +465 -465
- package/lib/ChunkRenderError.js +8 -0
- package/lib/ChunkTemplate.js +71 -71
- package/lib/Compilation.js +1 -1
- package/lib/Compiler.js +2 -1
- package/lib/ContextModule.js +8 -8
- package/lib/DllPlugin.js +3 -1
- package/lib/DllReferencePlugin.js +2 -1
- package/lib/Entrypoint.js +54 -54
- package/lib/EvalSourceMapDevToolModuleTemplatePlugin.js +115 -115
- package/lib/ExportPropertyMainTemplatePlugin.js +13 -0
- package/lib/Generator.js +52 -52
- package/lib/HotModuleReplacement.runtime.js +633 -633
- package/lib/JsonParser.js +2 -1
- package/lib/LibManifestPlugin.js +9 -0
- package/lib/LibraryTemplatePlugin.js +66 -33
- package/lib/MainTemplate.js +468 -468
- package/lib/Module.js +3 -3
- package/lib/ModuleDependencyError.js +12 -2
- package/lib/NormalModuleFactory.js +5 -3
- package/lib/Parser.js +27 -23
- package/lib/ProgressPlugin.js +1 -1
- package/lib/RecordIdsPlugin.js +3 -1
- package/lib/RuntimeTemplate.js +1 -1
- package/lib/SetVarMainTemplatePlugin.js +12 -0
- package/lib/SourceMapDevToolPlugin.js +11 -13
- package/lib/Template.js +289 -290
- package/lib/UmdMainTemplatePlugin.js +67 -32
- package/lib/WebpackError.js +8 -2
- package/lib/compareLocations.js +20 -0
- package/lib/debug/ProfilingPlugin.js +416 -416
- package/lib/dependencies/ContextDependencyHelpers.js +142 -142
- package/lib/dependencies/WebpackMissingModule.js +2 -2
- package/lib/optimize/RemoveEmptyChunksPlugin.js +42 -40
- package/lib/optimize/RuntimeChunkPlugin.js +9 -5
- package/lib/optimize/SplitChunksPlugin.js +195 -124
- package/lib/util/Queue.js +46 -46
- package/lib/util/SetHelpers.js +48 -48
- package/lib/util/SortableSet.js +106 -106
- package/lib/util/StackedSetMap.js +128 -128
- package/lib/util/cachedMerge.js +13 -0
- package/lib/util/identifier.js +5 -0
- package/lib/util/objectToMap.js +16 -16
- package/lib/wasm/WebAssemblyGenerator.js +280 -280
- package/lib/wasm/WebAssemblyParser.js +79 -79
- package/lib/web/JsonpMainTemplatePlugin.js +2 -2
- package/package.json +21 -17
- package/schemas/WebpackOptions.json +12 -1
- package/schemas/plugins/BannerPlugin.json +96 -85
- package/schemas/plugins/DllPlugin.json +4 -0
package/lib/MainTemplate.js
CHANGED
@@ -1,468 +1,468 @@
|
|
1
|
-
/*
|
2
|
-
MIT License http://www.opensource.org/licenses/mit-license.php
|
3
|
-
Author Tobias Koppers @sokra
|
4
|
-
*/
|
5
|
-
"use strict";
|
6
|
-
|
7
|
-
const {
|
8
|
-
ConcatSource,
|
9
|
-
OriginalSource,
|
10
|
-
PrefixSource,
|
11
|
-
RawSource
|
12
|
-
} = require("webpack-sources");
|
13
|
-
const {
|
14
|
-
Tapable,
|
15
|
-
SyncWaterfallHook,
|
16
|
-
SyncHook,
|
17
|
-
SyncBailHook
|
18
|
-
} = require("tapable");
|
19
|
-
const Template = require("./Template");
|
20
|
-
|
21
|
-
/** @typedef {import("webpack-sources").ConcatSource} ConcatSource */
|
22
|
-
/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
|
23
|
-
/** @typedef {import("./Chunk")} Chunk */
|
24
|
-
/** @typedef {import("./Module")} Module} */
|
25
|
-
/** @typedef {import("crypto").Hash} Hash} */
|
26
|
-
|
27
|
-
/**
|
28
|
-
* @typedef {Object} RenderManifestOptions
|
29
|
-
* @property {Chunk} chunk the chunk used to render
|
30
|
-
* @property {Hash} hash
|
31
|
-
* @property {string} fullHash
|
32
|
-
* @property {TODO} outputOptions
|
33
|
-
* @property {{javascript: ModuleTemplate, webassembly: ModuleTemplate}} moduleTemplates
|
34
|
-
* @property {Map<TODO, TODO>} dependencyTemplates
|
35
|
-
*/
|
36
|
-
|
37
|
-
// require function shortcuts:
|
38
|
-
// __webpack_require__.s = the module id of the entry point
|
39
|
-
// __webpack_require__.c = the module cache
|
40
|
-
// __webpack_require__.m = the module functions
|
41
|
-
// __webpack_require__.p = the bundle public path
|
42
|
-
// __webpack_require__.i = the identity function used for harmony imports
|
43
|
-
// __webpack_require__.e = the chunk ensure function
|
44
|
-
// __webpack_require__.d = the exported property define getter function
|
45
|
-
// __webpack_require__.o = Object.prototype.hasOwnProperty.call
|
46
|
-
// __webpack_require__.r = define compatibility on export
|
47
|
-
// __webpack_require__.n = compatibility get default export
|
48
|
-
// __webpack_require__.h = the webpack hash
|
49
|
-
// __webpack_require__.w = an object containing all installed WebAssembly.Modules keys by module id
|
50
|
-
// __webpack_require__.oe = the uncaught error handler for the webpack runtime
|
51
|
-
// __webpack_require__.nc = the script nonce
|
52
|
-
|
53
|
-
module.exports = class MainTemplate extends Tapable {
|
54
|
-
/**
|
55
|
-
*
|
56
|
-
* @param {TODO=} outputOptions output options for the MainTemplate
|
57
|
-
*/
|
58
|
-
constructor(outputOptions) {
|
59
|
-
super();
|
60
|
-
/** @type {TODO?} */
|
61
|
-
this.outputOptions = outputOptions || {};
|
62
|
-
this.hooks = {
|
63
|
-
/** @type {SyncWaterfallHook<TODO[], RenderManifestOptions>} */
|
64
|
-
renderManifest: new SyncWaterfallHook(["result", "options"]),
|
65
|
-
modules: new SyncWaterfallHook([
|
66
|
-
"modules",
|
67
|
-
"chunk",
|
68
|
-
"hash",
|
69
|
-
"moduleTemplate",
|
70
|
-
"dependencyTemplates"
|
71
|
-
]),
|
72
|
-
moduleObj: new SyncWaterfallHook([
|
73
|
-
"source",
|
74
|
-
"chunk",
|
75
|
-
"hash",
|
76
|
-
"moduleIdExpression"
|
77
|
-
]),
|
78
|
-
requireEnsure: new SyncWaterfallHook([
|
79
|
-
"source",
|
80
|
-
"chunk",
|
81
|
-
"hash",
|
82
|
-
"chunkIdExpression"
|
83
|
-
]),
|
84
|
-
bootstrap: new SyncWaterfallHook([
|
85
|
-
"source",
|
86
|
-
"chunk",
|
87
|
-
"hash",
|
88
|
-
"moduleTemplate",
|
89
|
-
"dependencyTemplates"
|
90
|
-
]),
|
91
|
-
localVars: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
92
|
-
require: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
93
|
-
requireExtensions: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
94
|
-
beforeStartup: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
95
|
-
startup: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
96
|
-
render: new SyncWaterfallHook([
|
97
|
-
"source",
|
98
|
-
"chunk",
|
99
|
-
"hash",
|
100
|
-
"moduleTemplate",
|
101
|
-
"dependencyTemplates"
|
102
|
-
]),
|
103
|
-
renderWithEntry: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
104
|
-
moduleRequire: new SyncWaterfallHook([
|
105
|
-
"source",
|
106
|
-
"chunk",
|
107
|
-
"hash",
|
108
|
-
"moduleIdExpression"
|
109
|
-
]),
|
110
|
-
addModule: new SyncWaterfallHook([
|
111
|
-
"source",
|
112
|
-
"chunk",
|
113
|
-
"hash",
|
114
|
-
"moduleIdExpression",
|
115
|
-
"moduleExpression"
|
116
|
-
]),
|
117
|
-
currentHash: new SyncWaterfallHook(["source", "requestedLength"]),
|
118
|
-
assetPath: new SyncWaterfallHook(["path", "options"]),
|
119
|
-
hash: new SyncHook(["hash"]),
|
120
|
-
hashForChunk: new SyncHook(["hash", "chunk"]),
|
121
|
-
globalHashPaths: new SyncWaterfallHook(["paths"]),
|
122
|
-
globalHash: new SyncBailHook(["chunk", "paths"]),
|
123
|
-
|
124
|
-
// TODO this should be moved somewhere else
|
125
|
-
// It's weird here
|
126
|
-
hotBootstrap: new SyncWaterfallHook(["source", "chunk", "hash"])
|
127
|
-
};
|
128
|
-
this.hooks.startup.tap("MainTemplate", (source, chunk, hash) => {
|
129
|
-
/** @type {string[]} */
|
130
|
-
const buf = [];
|
131
|
-
if (chunk.entryModule) {
|
132
|
-
buf.push("// Load entry module and return exports");
|
133
|
-
buf.push(
|
134
|
-
`return ${this.renderRequireFunctionForModule(
|
135
|
-
hash,
|
136
|
-
chunk,
|
137
|
-
JSON.stringify(chunk.entryModule.id)
|
138
|
-
)}(${this.requireFn}.s = ${JSON.stringify(chunk.entryModule.id)});`
|
139
|
-
);
|
140
|
-
}
|
141
|
-
return Template.asString(buf);
|
142
|
-
});
|
143
|
-
this.hooks.render.tap(
|
144
|
-
"MainTemplate",
|
145
|
-
(bootstrapSource, chunk, hash, moduleTemplate, dependencyTemplates) => {
|
146
|
-
const source = new ConcatSource();
|
147
|
-
source.add("/******/ (function(modules) { // webpackBootstrap\n");
|
148
|
-
source.add(new PrefixSource("/******/", bootstrapSource));
|
149
|
-
source.add("/******/ })\n");
|
150
|
-
source.add(
|
151
|
-
"/************************************************************************/\n"
|
152
|
-
);
|
153
|
-
source.add("/******/ (");
|
154
|
-
source.add(
|
155
|
-
this.hooks.modules.call(
|
156
|
-
new RawSource(""),
|
157
|
-
chunk,
|
158
|
-
hash,
|
159
|
-
moduleTemplate,
|
160
|
-
dependencyTemplates
|
161
|
-
)
|
162
|
-
);
|
163
|
-
source.add(")");
|
164
|
-
return source;
|
165
|
-
}
|
166
|
-
);
|
167
|
-
this.hooks.localVars.tap("MainTemplate", (source, chunk, hash) => {
|
168
|
-
return Template.asString([
|
169
|
-
source,
|
170
|
-
"// The module cache",
|
171
|
-
"var installedModules = {};"
|
172
|
-
]);
|
173
|
-
});
|
174
|
-
this.hooks.require.tap("MainTemplate", (source, chunk, hash) => {
|
175
|
-
return Template.asString([
|
176
|
-
source,
|
177
|
-
"// Check if module is in cache",
|
178
|
-
"if(installedModules[moduleId]) {",
|
179
|
-
Template.indent("return installedModules[moduleId].exports;"),
|
180
|
-
"}",
|
181
|
-
"// Create a new module (and put it into the cache)",
|
182
|
-
"var module = installedModules[moduleId] = {",
|
183
|
-
Template.indent(this.hooks.moduleObj.call("", chunk, hash, "moduleId")),
|
184
|
-
"};",
|
185
|
-
"",
|
186
|
-
Template.asString(
|
187
|
-
outputOptions.strictModuleExceptionHandling
|
188
|
-
? [
|
189
|
-
"// Execute the module function",
|
190
|
-
"var threw = true;",
|
191
|
-
"try {",
|
192
|
-
Template.indent([
|
193
|
-
`modules[moduleId].call(module.exports, module, module.exports, ${this.renderRequireFunctionForModule(
|
194
|
-
hash,
|
195
|
-
chunk,
|
196
|
-
"moduleId"
|
197
|
-
)});`,
|
198
|
-
"threw = false;"
|
199
|
-
]),
|
200
|
-
"} finally {",
|
201
|
-
Template.indent([
|
202
|
-
"if(threw) delete installedModules[moduleId];"
|
203
|
-
]),
|
204
|
-
"}"
|
205
|
-
]
|
206
|
-
: [
|
207
|
-
"// Execute the module function",
|
208
|
-
`modules[moduleId].call(module.exports, module, module.exports, ${this.renderRequireFunctionForModule(
|
209
|
-
hash,
|
210
|
-
chunk,
|
211
|
-
"moduleId"
|
212
|
-
)});`
|
213
|
-
]
|
214
|
-
),
|
215
|
-
"",
|
216
|
-
"// Flag the module as loaded",
|
217
|
-
"module.l = true;",
|
218
|
-
"",
|
219
|
-
"// Return the exports of the module",
|
220
|
-
"return module.exports;"
|
221
|
-
]);
|
222
|
-
});
|
223
|
-
this.hooks.moduleObj.tap(
|
224
|
-
"MainTemplate",
|
225
|
-
(source, chunk, hash, varModuleId) => {
|
226
|
-
return Template.asString(["i: moduleId,", "l: false,", "exports: {}"]);
|
227
|
-
}
|
228
|
-
);
|
229
|
-
this.hooks.requireExtensions.tap("MainTemplate", (source, chunk, hash) => {
|
230
|
-
const buf = [];
|
231
|
-
const chunkMaps = chunk.getChunkMaps();
|
232
|
-
// Check if there are non initial chunks which need to be imported using require-ensure
|
233
|
-
if (Object.keys(chunkMaps.hash).length) {
|
234
|
-
buf.push("// This file contains only the entry chunk.");
|
235
|
-
buf.push("// The chunk loading function for additional chunks");
|
236
|
-
buf.push(`${this.requireFn}.e = function requireEnsure(chunkId) {`);
|
237
|
-
buf.push(Template.indent("var promises = [];"));
|
238
|
-
buf.push(
|
239
|
-
Template.indent(
|
240
|
-
this.hooks.requireEnsure.call("", chunk, hash, "chunkId")
|
241
|
-
)
|
242
|
-
);
|
243
|
-
buf.push(Template.indent("return Promise.all(promises);"));
|
244
|
-
buf.push("};");
|
245
|
-
}
|
246
|
-
buf.push("");
|
247
|
-
buf.push("// expose the modules object (__webpack_modules__)");
|
248
|
-
buf.push(`${this.requireFn}.m = modules;`);
|
249
|
-
|
250
|
-
buf.push("");
|
251
|
-
buf.push("// expose the module cache");
|
252
|
-
buf.push(`${this.requireFn}.c = installedModules;`);
|
253
|
-
|
254
|
-
buf.push("");
|
255
|
-
buf.push("// define getter function for harmony exports");
|
256
|
-
buf.push(`${this.requireFn}.d = function(exports, name, getter) {`);
|
257
|
-
buf.push(
|
258
|
-
Template.indent([
|
259
|
-
`if(!${this.requireFn}.o(exports, name)) {`,
|
260
|
-
Template.indent([
|
261
|
-
"Object.defineProperty(exports, name, {",
|
262
|
-
Template.indent([
|
263
|
-
"configurable: false,",
|
264
|
-
"enumerable: true,",
|
265
|
-
"get: getter"
|
266
|
-
]),
|
267
|
-
"});"
|
268
|
-
]),
|
269
|
-
"}"
|
270
|
-
])
|
271
|
-
);
|
272
|
-
buf.push("};");
|
273
|
-
|
274
|
-
buf.push("");
|
275
|
-
buf.push("// define __esModule on exports");
|
276
|
-
buf.push(`${this.requireFn}.r = function(exports) {`);
|
277
|
-
buf.push(
|
278
|
-
Template.indent([
|
279
|
-
"Object.defineProperty(exports, '__esModule', { value: true });"
|
280
|
-
])
|
281
|
-
);
|
282
|
-
buf.push("};");
|
283
|
-
|
284
|
-
buf.push("");
|
285
|
-
buf.push(
|
286
|
-
"// getDefaultExport function for compatibility with non-harmony modules"
|
287
|
-
);
|
288
|
-
buf.push(this.requireFn + ".n = function(module) {");
|
289
|
-
buf.push(
|
290
|
-
Template.indent([
|
291
|
-
"var getter = module && module.__esModule ?",
|
292
|
-
Template.indent([
|
293
|
-
"function getDefault() { return module['default']; } :",
|
294
|
-
"function getModuleExports() { return module; };"
|
295
|
-
]),
|
296
|
-
`${this.requireFn}.d(getter, 'a', getter);`,
|
297
|
-
"return getter;"
|
298
|
-
])
|
299
|
-
);
|
300
|
-
buf.push("};");
|
301
|
-
|
302
|
-
buf.push("");
|
303
|
-
buf.push("// Object.prototype.hasOwnProperty.call");
|
304
|
-
buf.push(
|
305
|
-
`${
|
306
|
-
this.requireFn
|
307
|
-
}.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };`
|
308
|
-
);
|
309
|
-
|
310
|
-
const publicPath = this.getPublicPath({
|
311
|
-
hash: hash
|
312
|
-
});
|
313
|
-
buf.push("");
|
314
|
-
buf.push("// __webpack_public_path__");
|
315
|
-
buf.push(`${this.requireFn}.p = ${JSON.stringify(publicPath)};`);
|
316
|
-
return Template.asString(buf);
|
317
|
-
});
|
318
|
-
|
319
|
-
this.requireFn = "__webpack_require__";
|
320
|
-
}
|
321
|
-
|
322
|
-
/**
|
323
|
-
*
|
324
|
-
* @param {RenderManifestOptions} options render manifest options
|
325
|
-
* @returns {TODO[]} returns render manifest
|
326
|
-
*/
|
327
|
-
getRenderManifest(options) {
|
328
|
-
const result = [];
|
329
|
-
|
330
|
-
this.hooks.renderManifest.call(result, options);
|
331
|
-
|
332
|
-
return result;
|
333
|
-
}
|
334
|
-
|
335
|
-
/**
|
336
|
-
*
|
337
|
-
* @param {string} hash hash to be used for render call
|
338
|
-
* @param {Chunk} chunk Chunk instance
|
339
|
-
* @param {ModuleTemplate} moduleTemplate ModuleTemplate instance for render
|
340
|
-
* @param {TODO} dependencyTemplates DependencyTemplate[]s
|
341
|
-
* @returns {ConcatSource} the newly generated source from rendering
|
342
|
-
*/
|
343
|
-
render(hash, chunk, moduleTemplate, dependencyTemplates) {
|
344
|
-
const buf = [];
|
345
|
-
buf.push(
|
346
|
-
this.hooks.bootstrap.call(
|
347
|
-
"",
|
348
|
-
chunk,
|
349
|
-
hash,
|
350
|
-
moduleTemplate,
|
351
|
-
dependencyTemplates
|
352
|
-
)
|
353
|
-
);
|
354
|
-
buf.push(this.hooks.localVars.call("", chunk, hash));
|
355
|
-
buf.push("");
|
356
|
-
buf.push("// The require function");
|
357
|
-
buf.push(`function ${this.requireFn}(moduleId) {`);
|
358
|
-
buf.push(Template.indent(this.hooks.require.call("", chunk, hash)));
|
359
|
-
buf.push("}");
|
360
|
-
buf.push("");
|
361
|
-
buf.push(
|
362
|
-
Template.asString(this.hooks.requireExtensions.call("", chunk, hash))
|
363
|
-
);
|
364
|
-
buf.push("");
|
365
|
-
buf.push(Template.asString(this.hooks.beforeStartup.call("", chunk, hash)));
|
366
|
-
buf.push(Template.asString(this.hooks.startup.call("", chunk, hash)));
|
367
|
-
let source = this.hooks.render.call(
|
368
|
-
new OriginalSource(
|
369
|
-
Template.prefix(buf, " \t") + "\n",
|
370
|
-
"webpack/bootstrap"
|
371
|
-
),
|
372
|
-
chunk,
|
373
|
-
hash,
|
374
|
-
moduleTemplate,
|
375
|
-
dependencyTemplates
|
376
|
-
);
|
377
|
-
if (chunk.hasEntryModule()) {
|
378
|
-
source = this.hooks.renderWithEntry.call(source, chunk, hash);
|
379
|
-
}
|
380
|
-
if (!source)
|
381
|
-
throw new Error(
|
382
|
-
"Compiler error: MainTemplate plugin 'render' should return something"
|
383
|
-
);
|
384
|
-
chunk.rendered = true;
|
385
|
-
return new ConcatSource(source, ";");
|
386
|
-
}
|
387
|
-
|
388
|
-
/**
|
389
|
-
*
|
390
|
-
* @param {string} hash hash for render fn
|
391
|
-
* @param {Chunk} chunk Chunk instance for require
|
392
|
-
* @param {(number|string)=} varModuleId module id
|
393
|
-
* @returns {TODO} the moduleRequire hook call return signature
|
394
|
-
*/
|
395
|
-
renderRequireFunctionForModule(hash, chunk, varModuleId) {
|
396
|
-
return this.hooks.moduleRequire.call(
|
397
|
-
this.requireFn,
|
398
|
-
chunk,
|
399
|
-
hash,
|
400
|
-
varModuleId
|
401
|
-
);
|
402
|
-
}
|
403
|
-
|
404
|
-
/**
|
405
|
-
*
|
406
|
-
* @param {string} hash hash for render add fn
|
407
|
-
* @param {Chunk} chunk Chunk instance for require add fn
|
408
|
-
* @param {(string|number)=} varModuleId module id
|
409
|
-
* @param {Module} varModule Module instance
|
410
|
-
* @returns {TODO} renderAddModule call
|
411
|
-
*/
|
412
|
-
renderAddModule(hash, chunk, varModuleId, varModule) {
|
413
|
-
return this.hooks.addModule.call(
|
414
|
-
`modules[${varModuleId}] = ${varModule};`,
|
415
|
-
chunk,
|
416
|
-
hash,
|
417
|
-
varModuleId,
|
418
|
-
varModule
|
419
|
-
);
|
420
|
-
}
|
421
|
-
|
422
|
-
/**
|
423
|
-
*
|
424
|
-
* @param {string} hash string hash
|
425
|
-
* @param {number} length length
|
426
|
-
* @returns {string} call hook return
|
427
|
-
*/
|
428
|
-
renderCurrentHashCode(hash, length) {
|
429
|
-
length = length || Infinity;
|
430
|
-
return this.hooks.currentHash.call(
|
431
|
-
JSON.stringify(hash.substr(0, length)),
|
432
|
-
length
|
433
|
-
);
|
434
|
-
}
|
435
|
-
|
436
|
-
/**
|
437
|
-
*
|
438
|
-
* @param {object} options get public path options
|
439
|
-
* @returns {string} hook call
|
440
|
-
*/
|
441
|
-
getPublicPath(options) {
|
442
|
-
return this.hooks.assetPath.call(
|
443
|
-
this.outputOptions.publicPath || "",
|
444
|
-
options
|
445
|
-
);
|
446
|
-
}
|
447
|
-
|
448
|
-
getAssetPath(path, options) {
|
449
|
-
return this.hooks.assetPath.call(path, options);
|
450
|
-
}
|
451
|
-
|
452
|
-
updateHash(hash) {
|
453
|
-
hash.update("maintemplate");
|
454
|
-
hash.update("3");
|
455
|
-
hash.update(this.outputOptions.publicPath + "");
|
456
|
-
this.hooks.hash.call(hash);
|
457
|
-
}
|
458
|
-
|
459
|
-
updateHashForChunk(hash, chunk) {
|
460
|
-
this.updateHash(hash);
|
461
|
-
this.hooks.hashForChunk.call(hash, chunk);
|
462
|
-
}
|
463
|
-
|
464
|
-
useChunkHash(chunk) {
|
465
|
-
const paths = this.hooks.globalHashPaths.call([]);
|
466
|
-
return !this.hooks.globalHash.call(chunk, paths);
|
467
|
-
}
|
468
|
-
};
|
1
|
+
/*
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
3
|
+
Author Tobias Koppers @sokra
|
4
|
+
*/
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
const {
|
8
|
+
ConcatSource,
|
9
|
+
OriginalSource,
|
10
|
+
PrefixSource,
|
11
|
+
RawSource
|
12
|
+
} = require("webpack-sources");
|
13
|
+
const {
|
14
|
+
Tapable,
|
15
|
+
SyncWaterfallHook,
|
16
|
+
SyncHook,
|
17
|
+
SyncBailHook
|
18
|
+
} = require("tapable");
|
19
|
+
const Template = require("./Template");
|
20
|
+
|
21
|
+
/** @typedef {import("webpack-sources").ConcatSource} ConcatSource */
|
22
|
+
/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
|
23
|
+
/** @typedef {import("./Chunk")} Chunk */
|
24
|
+
/** @typedef {import("./Module")} Module} */
|
25
|
+
/** @typedef {import("crypto").Hash} Hash} */
|
26
|
+
|
27
|
+
/**
|
28
|
+
* @typedef {Object} RenderManifestOptions
|
29
|
+
* @property {Chunk} chunk the chunk used to render
|
30
|
+
* @property {Hash} hash
|
31
|
+
* @property {string} fullHash
|
32
|
+
* @property {TODO} outputOptions
|
33
|
+
* @property {{javascript: ModuleTemplate, webassembly: ModuleTemplate}} moduleTemplates
|
34
|
+
* @property {Map<TODO, TODO>} dependencyTemplates
|
35
|
+
*/
|
36
|
+
|
37
|
+
// require function shortcuts:
|
38
|
+
// __webpack_require__.s = the module id of the entry point
|
39
|
+
// __webpack_require__.c = the module cache
|
40
|
+
// __webpack_require__.m = the module functions
|
41
|
+
// __webpack_require__.p = the bundle public path
|
42
|
+
// __webpack_require__.i = the identity function used for harmony imports
|
43
|
+
// __webpack_require__.e = the chunk ensure function
|
44
|
+
// __webpack_require__.d = the exported property define getter function
|
45
|
+
// __webpack_require__.o = Object.prototype.hasOwnProperty.call
|
46
|
+
// __webpack_require__.r = define compatibility on export
|
47
|
+
// __webpack_require__.n = compatibility get default export
|
48
|
+
// __webpack_require__.h = the webpack hash
|
49
|
+
// __webpack_require__.w = an object containing all installed WebAssembly.Modules keys by module id
|
50
|
+
// __webpack_require__.oe = the uncaught error handler for the webpack runtime
|
51
|
+
// __webpack_require__.nc = the script nonce
|
52
|
+
|
53
|
+
module.exports = class MainTemplate extends Tapable {
|
54
|
+
/**
|
55
|
+
*
|
56
|
+
* @param {TODO=} outputOptions output options for the MainTemplate
|
57
|
+
*/
|
58
|
+
constructor(outputOptions) {
|
59
|
+
super();
|
60
|
+
/** @type {TODO?} */
|
61
|
+
this.outputOptions = outputOptions || {};
|
62
|
+
this.hooks = {
|
63
|
+
/** @type {SyncWaterfallHook<TODO[], RenderManifestOptions>} */
|
64
|
+
renderManifest: new SyncWaterfallHook(["result", "options"]),
|
65
|
+
modules: new SyncWaterfallHook([
|
66
|
+
"modules",
|
67
|
+
"chunk",
|
68
|
+
"hash",
|
69
|
+
"moduleTemplate",
|
70
|
+
"dependencyTemplates"
|
71
|
+
]),
|
72
|
+
moduleObj: new SyncWaterfallHook([
|
73
|
+
"source",
|
74
|
+
"chunk",
|
75
|
+
"hash",
|
76
|
+
"moduleIdExpression"
|
77
|
+
]),
|
78
|
+
requireEnsure: new SyncWaterfallHook([
|
79
|
+
"source",
|
80
|
+
"chunk",
|
81
|
+
"hash",
|
82
|
+
"chunkIdExpression"
|
83
|
+
]),
|
84
|
+
bootstrap: new SyncWaterfallHook([
|
85
|
+
"source",
|
86
|
+
"chunk",
|
87
|
+
"hash",
|
88
|
+
"moduleTemplate",
|
89
|
+
"dependencyTemplates"
|
90
|
+
]),
|
91
|
+
localVars: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
92
|
+
require: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
93
|
+
requireExtensions: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
94
|
+
beforeStartup: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
95
|
+
startup: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
96
|
+
render: new SyncWaterfallHook([
|
97
|
+
"source",
|
98
|
+
"chunk",
|
99
|
+
"hash",
|
100
|
+
"moduleTemplate",
|
101
|
+
"dependencyTemplates"
|
102
|
+
]),
|
103
|
+
renderWithEntry: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
104
|
+
moduleRequire: new SyncWaterfallHook([
|
105
|
+
"source",
|
106
|
+
"chunk",
|
107
|
+
"hash",
|
108
|
+
"moduleIdExpression"
|
109
|
+
]),
|
110
|
+
addModule: new SyncWaterfallHook([
|
111
|
+
"source",
|
112
|
+
"chunk",
|
113
|
+
"hash",
|
114
|
+
"moduleIdExpression",
|
115
|
+
"moduleExpression"
|
116
|
+
]),
|
117
|
+
currentHash: new SyncWaterfallHook(["source", "requestedLength"]),
|
118
|
+
assetPath: new SyncWaterfallHook(["path", "options"]),
|
119
|
+
hash: new SyncHook(["hash"]),
|
120
|
+
hashForChunk: new SyncHook(["hash", "chunk"]),
|
121
|
+
globalHashPaths: new SyncWaterfallHook(["paths"]),
|
122
|
+
globalHash: new SyncBailHook(["chunk", "paths"]),
|
123
|
+
|
124
|
+
// TODO this should be moved somewhere else
|
125
|
+
// It's weird here
|
126
|
+
hotBootstrap: new SyncWaterfallHook(["source", "chunk", "hash"])
|
127
|
+
};
|
128
|
+
this.hooks.startup.tap("MainTemplate", (source, chunk, hash) => {
|
129
|
+
/** @type {string[]} */
|
130
|
+
const buf = [];
|
131
|
+
if (chunk.entryModule) {
|
132
|
+
buf.push("// Load entry module and return exports");
|
133
|
+
buf.push(
|
134
|
+
`return ${this.renderRequireFunctionForModule(
|
135
|
+
hash,
|
136
|
+
chunk,
|
137
|
+
JSON.stringify(chunk.entryModule.id)
|
138
|
+
)}(${this.requireFn}.s = ${JSON.stringify(chunk.entryModule.id)});`
|
139
|
+
);
|
140
|
+
}
|
141
|
+
return Template.asString(buf);
|
142
|
+
});
|
143
|
+
this.hooks.render.tap(
|
144
|
+
"MainTemplate",
|
145
|
+
(bootstrapSource, chunk, hash, moduleTemplate, dependencyTemplates) => {
|
146
|
+
const source = new ConcatSource();
|
147
|
+
source.add("/******/ (function(modules) { // webpackBootstrap\n");
|
148
|
+
source.add(new PrefixSource("/******/", bootstrapSource));
|
149
|
+
source.add("/******/ })\n");
|
150
|
+
source.add(
|
151
|
+
"/************************************************************************/\n"
|
152
|
+
);
|
153
|
+
source.add("/******/ (");
|
154
|
+
source.add(
|
155
|
+
this.hooks.modules.call(
|
156
|
+
new RawSource(""),
|
157
|
+
chunk,
|
158
|
+
hash,
|
159
|
+
moduleTemplate,
|
160
|
+
dependencyTemplates
|
161
|
+
)
|
162
|
+
);
|
163
|
+
source.add(")");
|
164
|
+
return source;
|
165
|
+
}
|
166
|
+
);
|
167
|
+
this.hooks.localVars.tap("MainTemplate", (source, chunk, hash) => {
|
168
|
+
return Template.asString([
|
169
|
+
source,
|
170
|
+
"// The module cache",
|
171
|
+
"var installedModules = {};"
|
172
|
+
]);
|
173
|
+
});
|
174
|
+
this.hooks.require.tap("MainTemplate", (source, chunk, hash) => {
|
175
|
+
return Template.asString([
|
176
|
+
source,
|
177
|
+
"// Check if module is in cache",
|
178
|
+
"if(installedModules[moduleId]) {",
|
179
|
+
Template.indent("return installedModules[moduleId].exports;"),
|
180
|
+
"}",
|
181
|
+
"// Create a new module (and put it into the cache)",
|
182
|
+
"var module = installedModules[moduleId] = {",
|
183
|
+
Template.indent(this.hooks.moduleObj.call("", chunk, hash, "moduleId")),
|
184
|
+
"};",
|
185
|
+
"",
|
186
|
+
Template.asString(
|
187
|
+
outputOptions.strictModuleExceptionHandling
|
188
|
+
? [
|
189
|
+
"// Execute the module function",
|
190
|
+
"var threw = true;",
|
191
|
+
"try {",
|
192
|
+
Template.indent([
|
193
|
+
`modules[moduleId].call(module.exports, module, module.exports, ${this.renderRequireFunctionForModule(
|
194
|
+
hash,
|
195
|
+
chunk,
|
196
|
+
"moduleId"
|
197
|
+
)});`,
|
198
|
+
"threw = false;"
|
199
|
+
]),
|
200
|
+
"} finally {",
|
201
|
+
Template.indent([
|
202
|
+
"if(threw) delete installedModules[moduleId];"
|
203
|
+
]),
|
204
|
+
"}"
|
205
|
+
]
|
206
|
+
: [
|
207
|
+
"// Execute the module function",
|
208
|
+
`modules[moduleId].call(module.exports, module, module.exports, ${this.renderRequireFunctionForModule(
|
209
|
+
hash,
|
210
|
+
chunk,
|
211
|
+
"moduleId"
|
212
|
+
)});`
|
213
|
+
]
|
214
|
+
),
|
215
|
+
"",
|
216
|
+
"// Flag the module as loaded",
|
217
|
+
"module.l = true;",
|
218
|
+
"",
|
219
|
+
"// Return the exports of the module",
|
220
|
+
"return module.exports;"
|
221
|
+
]);
|
222
|
+
});
|
223
|
+
this.hooks.moduleObj.tap(
|
224
|
+
"MainTemplate",
|
225
|
+
(source, chunk, hash, varModuleId) => {
|
226
|
+
return Template.asString(["i: moduleId,", "l: false,", "exports: {}"]);
|
227
|
+
}
|
228
|
+
);
|
229
|
+
this.hooks.requireExtensions.tap("MainTemplate", (source, chunk, hash) => {
|
230
|
+
const buf = [];
|
231
|
+
const chunkMaps = chunk.getChunkMaps();
|
232
|
+
// Check if there are non initial chunks which need to be imported using require-ensure
|
233
|
+
if (Object.keys(chunkMaps.hash).length) {
|
234
|
+
buf.push("// This file contains only the entry chunk.");
|
235
|
+
buf.push("// The chunk loading function for additional chunks");
|
236
|
+
buf.push(`${this.requireFn}.e = function requireEnsure(chunkId) {`);
|
237
|
+
buf.push(Template.indent("var promises = [];"));
|
238
|
+
buf.push(
|
239
|
+
Template.indent(
|
240
|
+
this.hooks.requireEnsure.call("", chunk, hash, "chunkId")
|
241
|
+
)
|
242
|
+
);
|
243
|
+
buf.push(Template.indent("return Promise.all(promises);"));
|
244
|
+
buf.push("};");
|
245
|
+
}
|
246
|
+
buf.push("");
|
247
|
+
buf.push("// expose the modules object (__webpack_modules__)");
|
248
|
+
buf.push(`${this.requireFn}.m = modules;`);
|
249
|
+
|
250
|
+
buf.push("");
|
251
|
+
buf.push("// expose the module cache");
|
252
|
+
buf.push(`${this.requireFn}.c = installedModules;`);
|
253
|
+
|
254
|
+
buf.push("");
|
255
|
+
buf.push("// define getter function for harmony exports");
|
256
|
+
buf.push(`${this.requireFn}.d = function(exports, name, getter) {`);
|
257
|
+
buf.push(
|
258
|
+
Template.indent([
|
259
|
+
`if(!${this.requireFn}.o(exports, name)) {`,
|
260
|
+
Template.indent([
|
261
|
+
"Object.defineProperty(exports, name, {",
|
262
|
+
Template.indent([
|
263
|
+
"configurable: false,",
|
264
|
+
"enumerable: true,",
|
265
|
+
"get: getter"
|
266
|
+
]),
|
267
|
+
"});"
|
268
|
+
]),
|
269
|
+
"}"
|
270
|
+
])
|
271
|
+
);
|
272
|
+
buf.push("};");
|
273
|
+
|
274
|
+
buf.push("");
|
275
|
+
buf.push("// define __esModule on exports");
|
276
|
+
buf.push(`${this.requireFn}.r = function(exports) {`);
|
277
|
+
buf.push(
|
278
|
+
Template.indent([
|
279
|
+
"Object.defineProperty(exports, '__esModule', { value: true });"
|
280
|
+
])
|
281
|
+
);
|
282
|
+
buf.push("};");
|
283
|
+
|
284
|
+
buf.push("");
|
285
|
+
buf.push(
|
286
|
+
"// getDefaultExport function for compatibility with non-harmony modules"
|
287
|
+
);
|
288
|
+
buf.push(this.requireFn + ".n = function(module) {");
|
289
|
+
buf.push(
|
290
|
+
Template.indent([
|
291
|
+
"var getter = module && module.__esModule ?",
|
292
|
+
Template.indent([
|
293
|
+
"function getDefault() { return module['default']; } :",
|
294
|
+
"function getModuleExports() { return module; };"
|
295
|
+
]),
|
296
|
+
`${this.requireFn}.d(getter, 'a', getter);`,
|
297
|
+
"return getter;"
|
298
|
+
])
|
299
|
+
);
|
300
|
+
buf.push("};");
|
301
|
+
|
302
|
+
buf.push("");
|
303
|
+
buf.push("// Object.prototype.hasOwnProperty.call");
|
304
|
+
buf.push(
|
305
|
+
`${
|
306
|
+
this.requireFn
|
307
|
+
}.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };`
|
308
|
+
);
|
309
|
+
|
310
|
+
const publicPath = this.getPublicPath({
|
311
|
+
hash: hash
|
312
|
+
});
|
313
|
+
buf.push("");
|
314
|
+
buf.push("// __webpack_public_path__");
|
315
|
+
buf.push(`${this.requireFn}.p = ${JSON.stringify(publicPath)};`);
|
316
|
+
return Template.asString(buf);
|
317
|
+
});
|
318
|
+
|
319
|
+
this.requireFn = "__webpack_require__";
|
320
|
+
}
|
321
|
+
|
322
|
+
/**
|
323
|
+
*
|
324
|
+
* @param {RenderManifestOptions} options render manifest options
|
325
|
+
* @returns {TODO[]} returns render manifest
|
326
|
+
*/
|
327
|
+
getRenderManifest(options) {
|
328
|
+
const result = [];
|
329
|
+
|
330
|
+
this.hooks.renderManifest.call(result, options);
|
331
|
+
|
332
|
+
return result;
|
333
|
+
}
|
334
|
+
|
335
|
+
/**
|
336
|
+
*
|
337
|
+
* @param {string} hash hash to be used for render call
|
338
|
+
* @param {Chunk} chunk Chunk instance
|
339
|
+
* @param {ModuleTemplate} moduleTemplate ModuleTemplate instance for render
|
340
|
+
* @param {TODO} dependencyTemplates DependencyTemplate[]s
|
341
|
+
* @returns {ConcatSource} the newly generated source from rendering
|
342
|
+
*/
|
343
|
+
render(hash, chunk, moduleTemplate, dependencyTemplates) {
|
344
|
+
const buf = [];
|
345
|
+
buf.push(
|
346
|
+
this.hooks.bootstrap.call(
|
347
|
+
"",
|
348
|
+
chunk,
|
349
|
+
hash,
|
350
|
+
moduleTemplate,
|
351
|
+
dependencyTemplates
|
352
|
+
)
|
353
|
+
);
|
354
|
+
buf.push(this.hooks.localVars.call("", chunk, hash));
|
355
|
+
buf.push("");
|
356
|
+
buf.push("// The require function");
|
357
|
+
buf.push(`function ${this.requireFn}(moduleId) {`);
|
358
|
+
buf.push(Template.indent(this.hooks.require.call("", chunk, hash)));
|
359
|
+
buf.push("}");
|
360
|
+
buf.push("");
|
361
|
+
buf.push(
|
362
|
+
Template.asString(this.hooks.requireExtensions.call("", chunk, hash))
|
363
|
+
);
|
364
|
+
buf.push("");
|
365
|
+
buf.push(Template.asString(this.hooks.beforeStartup.call("", chunk, hash)));
|
366
|
+
buf.push(Template.asString(this.hooks.startup.call("", chunk, hash)));
|
367
|
+
let source = this.hooks.render.call(
|
368
|
+
new OriginalSource(
|
369
|
+
Template.prefix(buf, " \t") + "\n",
|
370
|
+
"webpack/bootstrap"
|
371
|
+
),
|
372
|
+
chunk,
|
373
|
+
hash,
|
374
|
+
moduleTemplate,
|
375
|
+
dependencyTemplates
|
376
|
+
);
|
377
|
+
if (chunk.hasEntryModule()) {
|
378
|
+
source = this.hooks.renderWithEntry.call(source, chunk, hash);
|
379
|
+
}
|
380
|
+
if (!source)
|
381
|
+
throw new Error(
|
382
|
+
"Compiler error: MainTemplate plugin 'render' should return something"
|
383
|
+
);
|
384
|
+
chunk.rendered = true;
|
385
|
+
return new ConcatSource(source, ";");
|
386
|
+
}
|
387
|
+
|
388
|
+
/**
|
389
|
+
*
|
390
|
+
* @param {string} hash hash for render fn
|
391
|
+
* @param {Chunk} chunk Chunk instance for require
|
392
|
+
* @param {(number|string)=} varModuleId module id
|
393
|
+
* @returns {TODO} the moduleRequire hook call return signature
|
394
|
+
*/
|
395
|
+
renderRequireFunctionForModule(hash, chunk, varModuleId) {
|
396
|
+
return this.hooks.moduleRequire.call(
|
397
|
+
this.requireFn,
|
398
|
+
chunk,
|
399
|
+
hash,
|
400
|
+
varModuleId
|
401
|
+
);
|
402
|
+
}
|
403
|
+
|
404
|
+
/**
|
405
|
+
*
|
406
|
+
* @param {string} hash hash for render add fn
|
407
|
+
* @param {Chunk} chunk Chunk instance for require add fn
|
408
|
+
* @param {(string|number)=} varModuleId module id
|
409
|
+
* @param {Module} varModule Module instance
|
410
|
+
* @returns {TODO} renderAddModule call
|
411
|
+
*/
|
412
|
+
renderAddModule(hash, chunk, varModuleId, varModule) {
|
413
|
+
return this.hooks.addModule.call(
|
414
|
+
`modules[${varModuleId}] = ${varModule};`,
|
415
|
+
chunk,
|
416
|
+
hash,
|
417
|
+
varModuleId,
|
418
|
+
varModule
|
419
|
+
);
|
420
|
+
}
|
421
|
+
|
422
|
+
/**
|
423
|
+
*
|
424
|
+
* @param {string} hash string hash
|
425
|
+
* @param {number} length length
|
426
|
+
* @returns {string} call hook return
|
427
|
+
*/
|
428
|
+
renderCurrentHashCode(hash, length) {
|
429
|
+
length = length || Infinity;
|
430
|
+
return this.hooks.currentHash.call(
|
431
|
+
JSON.stringify(hash.substr(0, length)),
|
432
|
+
length
|
433
|
+
);
|
434
|
+
}
|
435
|
+
|
436
|
+
/**
|
437
|
+
*
|
438
|
+
* @param {object} options get public path options
|
439
|
+
* @returns {string} hook call
|
440
|
+
*/
|
441
|
+
getPublicPath(options) {
|
442
|
+
return this.hooks.assetPath.call(
|
443
|
+
this.outputOptions.publicPath || "",
|
444
|
+
options
|
445
|
+
);
|
446
|
+
}
|
447
|
+
|
448
|
+
getAssetPath(path, options) {
|
449
|
+
return this.hooks.assetPath.call(path, options);
|
450
|
+
}
|
451
|
+
|
452
|
+
updateHash(hash) {
|
453
|
+
hash.update("maintemplate");
|
454
|
+
hash.update("3");
|
455
|
+
hash.update(this.outputOptions.publicPath + "");
|
456
|
+
this.hooks.hash.call(hash);
|
457
|
+
}
|
458
|
+
|
459
|
+
updateHashForChunk(hash, chunk) {
|
460
|
+
this.updateHash(hash);
|
461
|
+
this.hooks.hashForChunk.call(hash, chunk);
|
462
|
+
}
|
463
|
+
|
464
|
+
useChunkHash(chunk) {
|
465
|
+
const paths = this.hooks.globalHashPaths.call([]);
|
466
|
+
return !this.hooks.globalHash.call(chunk, paths);
|
467
|
+
}
|
468
|
+
};
|