Skip to content

Commit 6aa6f8c

Browse files
committed
WIP: move stuff to RuntimeTemplate
1 parent a1f8890 commit 6aa6f8c

File tree

32 files changed

+356
-277
lines changed

32 files changed

+356
-277
lines changed

lib/ContextModule.js

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ const Module = require("./Module");
99
const OriginalSource = require("webpack-sources").OriginalSource;
1010
const RawSource = require("webpack-sources").RawSource;
1111
const AsyncDependenciesBlock = require("./AsyncDependenciesBlock");
12-
const DepBlockHelpers = require("./dependencies/DepBlockHelpers");
1312
const Template = require("./Template");
1413

1514
class ContextModule extends Module {
@@ -275,8 +274,11 @@ function webpackContext(req) {
275274
}
276275
function webpackContextResolve(req) {
277276
var id = map[req];
278-
if(!(id + 1)) // check for number or string
279-
throw new Error("Cannot find module '" + req + "'.");
277+
if(!(id + 1)) { // check for number or string
278+
var e = new Error('Cannot find module "' + req + '".');
279+
e.code = 'MODULE_NOT_FOUND';
280+
throw e;
281+
}
280282
return id;
281283
}
282284
webpackContext.keys = function webpackContextKeys() {
@@ -297,15 +299,21 @@ ${typeof fakeMap === "object" ? `var fakeMap = ${JSON.stringify(fakeMap, null, "
297299
298300
function webpackContext(req) {
299301
var id = webpackContextResolve(req);
300-
if(!__webpack_require__.m[id])
301-
throw new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
302+
if(!__webpack_require__.m[id]) {
303+
var e = new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
304+
e.code = 'MODULE_NOT_FOUND';
305+
throw e;
306+
}
302307
var module = __webpack_require__(id);
303308
${returnModuleObject}
304309
}
305310
function webpackContextResolve(req) {
306311
var id = map[req];
307-
if(!(id + 1)) // check for number or string
308-
throw new Error("Cannot find module '" + req + "'.");
312+
if(!(id + 1)) { // check for number or string
313+
var e = new Error('Cannot find module "' + req + '".');
314+
e.code = 'MODULE_NOT_FOUND';
315+
throw e;
316+
}
309317
return id;
310318
}
311319
webpackContext.keys = function webpackContextKeys() {
@@ -326,8 +334,11 @@ ${typeof fakeMap === "object" ? `var fakeMap = ${JSON.stringify(fakeMap, null, "
326334
327335
function webpackAsyncContext(req) {
328336
return webpackAsyncContextResolve(req).then(function(id) {
329-
if(!__webpack_require__.m[id])
330-
throw new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
337+
if(!__webpack_require__.m[id]) {
338+
var e = new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
339+
e.code = 'MODULE_NOT_FOUND';
340+
throw e;
341+
}
331342
var module = __webpack_require__(id);
332343
${returnModuleObject}
333344
});
@@ -337,8 +348,11 @@ function webpackAsyncContextResolve(req) {
337348
// uncatched exception popping up in devtools
338349
return Promise.resolve().then(function() {
339350
var id = map[req];
340-
if(!(id + 1)) // check for number or string
341-
throw new Error("Cannot find module '" + req + "'.");
351+
if(!(id + 1)) { // check for number or string
352+
var e = new Error('Cannot find module "' + req + '".');
353+
e.code = 'MODULE_NOT_FOUND';
354+
throw e;
355+
}
342356
return id;
343357
});
344358
}
@@ -370,8 +384,11 @@ function webpackAsyncContextResolve(req) {
370384
// uncatched exception popping up in devtools
371385
return Promise.resolve().then(function() {
372386
var id = map[req];
373-
if(!(id + 1)) // check for number or string
374-
throw new Error("Cannot find module '" + req + "'.");
387+
if(!(id + 1)) { // check for number or string
388+
var e = new Error('Cannot find module "' + req + '".');
389+
e.code = 'MODULE_NOT_FOUND';
390+
throw e;
391+
}
375392
return id;
376393
});
377394
}
@@ -384,7 +401,10 @@ module.exports = webpackAsyncContext;`;
384401
}
385402

386403
getLazyOnceSource(block, dependencies, id, runtimeTemplate) {
387-
const promise = DepBlockHelpers.getDepBlockPromise(block, runtimeTemplate, "lazy-once context");
404+
const promise = runtimeTemplate.blockPromise({
405+
block,
406+
message: "lazy-once context"
407+
});
388408
const map = this.getUserRequestMap(dependencies);
389409
const fakeMap = this.getFakeMap(dependencies);
390410
const thenFunction = fakeMap ?
@@ -403,8 +423,11 @@ function webpackAsyncContext(req) {
403423
function webpackAsyncContextResolve(req) {
404424
return ${promise}.then(function() {
405425
var id = map[req];
406-
if(!(id + 1)) // check for number or string
407-
throw new Error("Cannot find module '" + req + "'.");
426+
if(!(id + 1)) { // check for number or string
427+
var e = new Error('Cannot find module "' + req + '".');
428+
e.code = 'MODULE_NOT_FOUND';
429+
throw e;
430+
}
408431
return id;
409432
});
410433
}
@@ -451,8 +474,13 @@ module.exports = webpackAsyncContext;`;
451474
return `var map = ${JSON.stringify(map, null, "\t")};
452475
function webpackAsyncContext(req) {
453476
var ids = map[req];
454-
if(!ids)
455-
return Promise.resolve().then(function() { throw new Error("Cannot find module '" + req + "'."); });
477+
if(!ids) {
478+
return Promise.resolve().then(function() {
479+
var e = new Error('Cannot find module "' + req + '".');
480+
e.code = 'MODULE_NOT_FOUND';
481+
throw e;
482+
});
483+
}
456484
return ${requestPrefix}.then(function() {
457485
var module = __webpack_require__(ids[0]);
458486
${returnModuleObject}
@@ -467,7 +495,9 @@ module.exports = webpackAsyncContext;`;
467495

468496
getSourceForEmptyContext(id) {
469497
return `function webpackEmptyContext(req) {
470-
throw new Error("Cannot find module '" + req + "'.");
498+
var e = new Error('Cannot find module "' + req + '".');
499+
e.code = 'MODULE_NOT_FOUND';
500+
throw e;
471501
}
472502
webpackEmptyContext.keys = function() { return []; };
473503
webpackEmptyContext.resolve = webpackEmptyContext;
@@ -480,7 +510,9 @@ webpackEmptyContext.id = ${JSON.stringify(id)};`;
480510
// Here Promise.resolve().then() is used instead of new Promise() to prevent
481511
// uncatched exception popping up in devtools
482512
return Promise.resolve().then(function() {
483-
throw new Error("Cannot find module '" + req + "'.");
513+
var e = new Error('Cannot find module "' + req + '".');
514+
e.code = 'MODULE_NOT_FOUND';
515+
throw e;
484516
});
485517
}
486518
webpackEmptyAsyncContext.keys = function() { return []; };

lib/RuntimeTemplate.js

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,120 @@
44
*/
55
"use strict";
66

7+
const Template = require("./Template");
8+
79
module.exports = class RuntimeTemplate {
810
constructor(outputOptions, requestShortener) {
911
this.outputOptions = outputOptions || {};
1012
this.requestShortener = requestShortener;
1113
}
14+
15+
comment({ request, chunkName, chunkReason, message }) {
16+
let content;
17+
if(this.outputOptions.pathinfo) {
18+
content = [message, request, chunkName, chunkReason].filter(Boolean).map(item => this.requestShortener.shorten(item)).join(" | ");
19+
} else {
20+
content = [message, chunkName, chunkReason].filter(Boolean).map(item => this.requestShortener.shorten(item)).join(" | ");
21+
}
22+
if(!content) return "";
23+
if(this.outputOptions.pathinfo) {
24+
return Template.toComment(content);
25+
} else {
26+
return Template.toNormalComment(content);
27+
}
28+
}
29+
30+
throwMissingModuleErrorFunction({ request }) {
31+
const err = `Cannot find module "${request}"`;
32+
return `function webpackMissingModule() { var e = new Error(${JSON.stringify(err)}); e.code = 'MODULE_NOT_FOUND'; throw e; }`;
33+
}
34+
35+
missingModule({ request }) {
36+
return `!(${this.throwMissingModuleErrorFunction({ request })}())`;
37+
}
38+
39+
missingModulePromise({ request }) {
40+
return `Promise.resolve().then(${this.throwMissingModuleErrorFunction({ request })})`;
41+
}
42+
43+
moduleId({ module, request }) {
44+
if(!module) return this.missingModule({ request });
45+
return `${this.comment({ request })}${JSON.stringify(module.id)}`;
46+
}
47+
48+
moduleExports({ module, request }) {
49+
if(!module) return this.missingModule({ request });
50+
return `__webpack_require__(${this.moduleId({ module, request })})`;
51+
}
52+
53+
moduleNamespace({ module, request, strict }) {
54+
const stringifiedId = JSON.stringify(module.id);
55+
const comment = this.comment({ request });
56+
if(module.buildMeta && module.buildMeta.harmonyModule) {
57+
return `__webpack_require__(${comment}${stringifiedId})`;
58+
} else if(strict) {
59+
return `Object({ /* fake namespace object */ "default": __webpack_require__(${comment}${stringifiedId}) })`;
60+
} else {
61+
return `Object(function() { var module = __webpack_require__(${comment}${stringifiedId}); return typeof module === "object" && module && module.__esModule ? module : { /* fake namespace object */ "default": module }; }())`;
62+
}
63+
}
64+
65+
moduleNamespacePromise({ block, module, request, message, strict, weak }) {
66+
if(!module) return this.missingModulePromise({ request });
67+
const promise = this.blockPromise({
68+
block,
69+
message
70+
});
71+
72+
let getModuleFunction;
73+
let idExpr = JSON.stringify(module.id);
74+
const comment = this.comment({ request });
75+
let header = "";
76+
if(weak) {
77+
if(idExpr.length > 8) { // 'var x="nnnnnn";x,"+x+",x' vs '"nnnnnn",nnnnnn,"nnnnnn"'
78+
header += `var id = ${idExpr}; `;
79+
idExpr = "id";
80+
}
81+
header += `if(!__webpack_require__.m[${idExpr}]) { var e = new Error("Module '" + ${idExpr} + "' is not available (weak dependency)"); e.code = 'MODULE_NOT_FOUND'; throw e; } `;
82+
}
83+
if(module.buildMeta && module.buildMeta.harmonyModule) {
84+
if(header) {
85+
getModuleFunction = `function() { ${header}return __webpack_require__(${comment}${idExpr}); }`;
86+
} else {
87+
getModuleFunction = `__webpack_require__.bind(null, ${comment}${idExpr})`;
88+
}
89+
} else if(strict) {
90+
getModuleFunction = `function() { ${header}return { /* fake namespace object */ "default": __webpack_require__(${comment}${idExpr}) }; }`;
91+
} else {
92+
getModuleFunction = `function() { ${header}var module = __webpack_require__(${comment}${idExpr}); return typeof module === "object" && module && module.__esModule ? module : { /* fake namespace object */ "default": module }; }`;
93+
}
94+
95+
return `${promise || "Promise.resolve()"}.then(${getModuleFunction})`;
96+
}
97+
98+
blockPromise({ block, message }) {
99+
if(!block || !block.chunks) {
100+
const comment = this.comment({ message });
101+
return `Promise.resolve(${comment})`;
102+
}
103+
const chunks = block.chunks.filter(chunk => !chunk.hasRuntime() && chunk.id !== null);
104+
const comment = this.comment({
105+
message,
106+
chunkName: block.chunkName,
107+
chunkReason: block.chunkReason
108+
});
109+
if(chunks.length === 1) {
110+
const chunkId = JSON.stringify(chunks[0].id);
111+
return `__webpack_require__.e(${comment}${chunkId})`;
112+
} else if(chunks.length > 0) {
113+
const requireChunkId = chunk => `__webpack_require__.e(${JSON.stringify(chunk.id)})`;
114+
return `Promise.all(${comment}[${chunks.map(requireChunkId).join(", ")}])`;
115+
} else {
116+
return `Promise.resolve(${comment})`;
117+
}
118+
}
119+
120+
onError() {
121+
return "__webpack_require__.oe";
122+
}
12123
};

lib/dependencies/AMDRequireArrayDependency.js

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
*/
55
"use strict";
66
const Dependency = require("../Dependency");
7-
const Template = require("../Template");
8-
const webpackMissingModuleModule = require("./WebpackMissingModule").module;
97

108
class AMDRequireArrayDependency extends Dependency {
119
constructor(depsArray, range) {
@@ -27,25 +25,24 @@ AMDRequireArrayDependency.Template = class AMDRequireArrayDependencyTemplate {
2725

2826
getContent(dep, runtime) {
2927
const requires = dep.depsArray.map((dependency) => {
30-
const optionalComment = runtime.outputOptions.pathinfo ? Template.toComment(runtime.requestShortener.shorten(dependency.request)) : "";
31-
return this.contentForDependency(dependency, optionalComment);
28+
return this.contentForDependency(dependency, runtime);
3229
});
3330
return `[${requires.join(", ")}]`;
3431
}
3532

36-
contentForDependency(dep, comment) {
33+
contentForDependency(dep, runtime) {
3734
if(typeof dep === "string") {
3835
return dep;
3936
}
4037

41-
if(dep.module) {
42-
const stringifiedId = JSON.stringify(dep.module.id);
43-
return `__webpack_require__(${comment}${stringifiedId})`;
44-
} else if(dep.localModule) {
38+
if(dep.localModule) {
4539
return dep.localModule.variableName();
40+
} else {
41+
return runtime.moduleExports({
42+
module: dep.module,
43+
request: dep.request
44+
});
4645
}
47-
48-
return webpackMissingModuleModule(dep.request);
4946
}
5047
};
5148

lib/dependencies/AMDRequireDependency.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
"use strict";
66
const NullDependency = require("./NullDependency");
7-
const DepBlockHelpers = require("./DepBlockHelpers");
87

98
class AMDRequireDependency extends NullDependency {
109
constructor(block) {
@@ -16,49 +15,52 @@ class AMDRequireDependency extends NullDependency {
1615
AMDRequireDependency.Template = class AMDRequireDependencyTemplate {
1716
apply(dep, source, runtime) {
1817
const depBlock = dep.block;
19-
const wrapper = DepBlockHelpers.getLoadDepBlockWrapper(depBlock, runtime, "require");
18+
const promise = runtime.blockPromise({
19+
block: depBlock,
20+
message: "AMD require"
21+
});
2022

2123
// has array range but no function range
2224
if(depBlock.arrayRange && !depBlock.functionRange) {
23-
const startBlock = wrapper[0] + "function() {";
24-
const endBlock = `;}${wrapper[1]}__webpack_require__.oe${wrapper[2]}`;
25+
const startBlock = `${promise}.then(function() {`;
26+
const endBlock = `;}).catch(${runtime.onError()})`;
2527
source.replace(depBlock.outerRange[0], depBlock.arrayRange[0] - 1, startBlock);
2628
source.replace(depBlock.arrayRange[1], depBlock.outerRange[1] - 1, endBlock);
2729
return;
2830
}
2931

3032
// has function range but no array range
3133
if(depBlock.functionRange && !depBlock.arrayRange) {
32-
const startBlock = wrapper[0] + "function() {(";
33-
const endBlock = `.call(exports, __webpack_require__, exports, module));}${wrapper[1]}__webpack_require__.oe${wrapper[2]}`;
34+
const startBlock = `${promise}.then((`;
35+
const endBlock = `).bind(exports, __webpack_require__, exports, module)).catch(${runtime.onError()})`;
3436
source.replace(depBlock.outerRange[0], depBlock.functionRange[0] - 1, startBlock);
3537
source.replace(depBlock.functionRange[1], depBlock.outerRange[1] - 1, endBlock);
3638
return;
3739
}
3840

3941
// has array range, function range, and errorCallbackRange
4042
if(depBlock.arrayRange && depBlock.functionRange && depBlock.errorCallbackRange) {
41-
const startBlock = wrapper[0] + "function() { ";
42-
const errorRangeBlock = `}${depBlock.functionBindThis ? ".bind(this)" : ""}${wrapper[1]}`;
43-
const endBlock = `${depBlock.errorCallbackBindThis ? ".bind(this)" : ""}${wrapper[2]}`;
43+
const startBlock = `${promise}.then(function() { `;
44+
const errorRangeBlock = `}${depBlock.functionBindThis ? ".bind(this)" : ""}).catch(`;
45+
const endBlock = `${depBlock.errorCallbackBindThis ? ".bind(this)" : ""})`;
4446

4547
source.replace(depBlock.outerRange[0], depBlock.arrayRange[0] - 1, startBlock);
4648
source.insert(depBlock.arrayRange[0] + 0.9, "var __WEBPACK_AMD_REQUIRE_ARRAY__ = ");
47-
source.replace(depBlock.arrayRange[1], depBlock.functionRange[0] - 1, "; ((");
48-
source.insert(depBlock.functionRange[1], ").apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__));");
49+
source.replace(depBlock.arrayRange[1], depBlock.functionRange[0] - 1, "; (");
50+
source.insert(depBlock.functionRange[1], ").apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);");
4951
source.replace(depBlock.functionRange[1], depBlock.errorCallbackRange[0] - 1, errorRangeBlock);
5052
source.replace(depBlock.errorCallbackRange[1], depBlock.outerRange[1] - 1, endBlock);
5153
return;
5254
}
5355

5456
// has array range, function range, but no errorCallbackRange
5557
if(depBlock.arrayRange && depBlock.functionRange) {
56-
const startBlock = wrapper[0] + "function() { ";
57-
const endBlock = `}${depBlock.functionBindThis ? ".bind(this)" : ""}${wrapper[1]}__webpack_require__.oe${wrapper[2]}`;
58+
const startBlock = `${promise}.then(function() { `;
59+
const endBlock = `}${depBlock.functionBindThis ? ".bind(this)" : ""}).catch(__webpack_require__.oe)`;
5860
source.replace(depBlock.outerRange[0], depBlock.arrayRange[0] - 1, startBlock);
5961
source.insert(depBlock.arrayRange[0] + 0.9, "var __WEBPACK_AMD_REQUIRE_ARRAY__ = ");
60-
source.replace(depBlock.arrayRange[1], depBlock.functionRange[0] - 1, "; ((");
61-
source.insert(depBlock.functionRange[1], ").apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__));");
62+
source.replace(depBlock.arrayRange[1], depBlock.functionRange[0] - 1, "; (");
63+
source.insert(depBlock.functionRange[1], ").apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);");
6264
source.replace(depBlock.functionRange[1], depBlock.outerRange[1] - 1, endBlock);
6365
}
6466
}

0 commit comments

Comments
 (0)