Skip to content

Commit 8543739

Browse files
sendilkumarnsokra
authored andcommitted
Refactor(ES6): JsonpMainTemplatePlugin
1 parent 0d31e0b commit 8543739

File tree

1 file changed

+181
-187
lines changed

1 file changed

+181
-187
lines changed

lib/JsonpMainTemplatePlugin.js

Lines changed: 181 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -2,207 +2,201 @@
22
MIT License http://www.opensource.org/licenses/mit-license.php
33
Author Tobias Koppers @sokra
44
*/
5-
var Template = require("./Template");
5+
"use strict";
66

7-
function JsonpMainTemplatePlugin() {}
8-
module.exports = JsonpMainTemplatePlugin;
7+
const Template = require("./Template");
8+
9+
class JsonpMainTemplatePlugin {
910

10-
JsonpMainTemplatePlugin.prototype.constructor = JsonpMainTemplatePlugin;
11-
JsonpMainTemplatePlugin.prototype.apply = function(mainTemplate) {
12-
mainTemplate.plugin("local-vars", function(source, chunk) {
13-
if(chunk.chunks.length > 0) {
11+
apply(mainTemplate) {
12+
mainTemplate.plugin("local-vars", function(source, chunk) {
13+
if(chunk.chunks.length > 0) {
14+
return this.asString([
15+
source,
16+
"",
17+
"// objects to store loaded and loading chunks",
18+
"var installedChunks = {",
19+
this.indent(
20+
chunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(",\n")
21+
),
22+
"};"
23+
]);
24+
}
25+
return source;
26+
});
27+
mainTemplate.plugin("jsonp-script", function(_, chunk, hash) {
28+
const chunkFilename = this.outputOptions.chunkFilename;
29+
const chunkMaps = chunk.getChunkMaps();
30+
const crossOriginLoading = this.outputOptions.crossOriginLoading;
31+
const chunkLoadTimeout = this.outputOptions.chunkLoadTimeout || 120000;
1432
return this.asString([
15-
source,
16-
"",
17-
"// objects to store loaded and loading chunks",
18-
"var installedChunks = {",
19-
this.indent(
20-
chunk.ids.map(function(id) {
21-
return JSON.stringify(id) + ": 0";
22-
}).join(",\n")
23-
),
24-
"};"
33+
"var script = document.createElement('script');",
34+
"script.type = 'text/javascript';",
35+
"script.charset = 'utf-8';",
36+
"script.async = true;",
37+
`script.timeout = ${chunkLoadTimeout};`,
38+
crossOriginLoading ? `script.crossOrigin = '${crossOriginLoading}';` : "",
39+
`if (${this.requireFn}.nc) {`,
40+
this.indent(`script.setAttribute("nonce", ${this.requireFn}.nc);`),
41+
"}",
42+
`script.src = ${this.requireFn}.p + ${this.applyPluginsWaterfall("asset-path", JSON.stringify(chunkFilename), {
43+
hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"",
44+
hashWithLength: length => "\" + " + this.renderCurrentHashCode(hash, length) + " + \"",
45+
chunk: {
46+
id: "\" + chunkId + \"",
47+
hash: "\" + " + JSON.stringify(chunkMaps.hash) + "[chunkId] + \"",
48+
hashWithLength(length) {
49+
const shortChunkHashMap = {};
50+
Object.keys(chunkMaps.hash).forEach(chunkId => {
51+
if(typeof chunkMaps.hash[chunkId] === "string")
52+
shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(0, length);
53+
});
54+
return "\" + " + JSON.stringify(shortChunkHashMap) + "[chunkId] + \"";
55+
},
56+
name: "\" + (" + JSON.stringify(chunkMaps.name) + "[chunkId]||chunkId) + \""
57+
}
58+
})};`,
59+
"var timeout = setTimeout(onScriptComplete, " + chunkLoadTimeout + ");",
60+
"script.onerror = script.onload = onScriptComplete;",
61+
"function onScriptComplete() {",
62+
this.indent([
63+
"// avoid mem leaks in IE.",
64+
"script.onerror = script.onload = null;",
65+
"clearTimeout(timeout);",
66+
"var chunk = installedChunks[chunkId];",
67+
"if(chunk !== 0) {",
68+
this.indent([
69+
"if(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));",
70+
"installedChunks[chunkId] = undefined;"
71+
]),
72+
"}"
73+
]),
74+
"};",
2575
]);
26-
}
27-
return source;
28-
});
29-
mainTemplate.plugin("jsonp-script", function(_, chunk, hash) {
30-
var chunkFilename = this.outputOptions.chunkFilename;
31-
var chunkMaps = chunk.getChunkMaps();
32-
var crossOriginLoading = this.outputOptions.crossOriginLoading;
33-
var chunkLoadTimeout = this.outputOptions.chunkLoadTimeout || 120000;
34-
return this.asString([
35-
"var script = document.createElement('script');",
36-
"script.type = 'text/javascript';",
37-
"script.charset = 'utf-8';",
38-
"script.async = true;",
39-
"script.timeout = " + chunkLoadTimeout + ";",
40-
crossOriginLoading ? "script.crossOrigin = '" + crossOriginLoading + "';" : "",
41-
"if (" + this.requireFn + ".nc) {",
42-
this.indent("script.setAttribute(\"nonce\", " + this.requireFn + ".nc);"),
43-
"}",
44-
"script.src = " + this.requireFn + ".p + " +
45-
this.applyPluginsWaterfall("asset-path", JSON.stringify(chunkFilename), {
46-
hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"",
47-
hashWithLength: function(length) {
48-
return "\" + " + this.renderCurrentHashCode(hash, length) + " + \"";
49-
}.bind(this),
50-
chunk: {
51-
id: "\" + chunkId + \"",
52-
hash: "\" + " + JSON.stringify(chunkMaps.hash) + "[chunkId] + \"",
53-
hashWithLength: function(length) {
54-
var shortChunkHashMap = {};
55-
Object.keys(chunkMaps.hash).forEach(function(chunkId) {
56-
if(typeof chunkMaps.hash[chunkId] === "string")
57-
shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(0, length);
58-
});
59-
return "\" + " + JSON.stringify(shortChunkHashMap) + "[chunkId] + \"";
60-
},
61-
name: "\" + (" + JSON.stringify(chunkMaps.name) + "[chunkId]||chunkId) + \""
62-
}
63-
}) + ";",
64-
"var timeout = setTimeout(onScriptComplete, " + chunkLoadTimeout + ");",
65-
"script.onerror = script.onload = onScriptComplete;",
66-
"function onScriptComplete() {",
67-
this.indent([
68-
"// avoid mem leaks in IE.",
69-
"script.onerror = script.onload = null;",
70-
"clearTimeout(timeout);",
71-
"var chunk = installedChunks[chunkId];",
72-
"if(chunk !== 0) {",
76+
});
77+
mainTemplate.plugin("require-ensure", function(_, chunk, hash) {
78+
return this.asString([
79+
"if(installedChunks[chunkId] === 0)",
80+
this.indent([
81+
"return Promise.resolve();"
82+
]),
83+
"",
84+
"// a Promise means \"currently loading\".",
85+
"if(installedChunks[chunkId]) {",
7386
this.indent([
74-
"if(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));",
75-
"installedChunks[chunkId] = undefined;"
87+
"return installedChunks[chunkId][2];"
7688
]),
77-
"}"
78-
]),
79-
"};",
80-
]);
81-
});
82-
mainTemplate.plugin("require-ensure", function(_, chunk, hash) {
83-
return this.asString([
84-
"if(installedChunks[chunkId] === 0)",
85-
this.indent([
86-
"return Promise.resolve();"
87-
]),
88-
"",
89-
"// a Promise means \"currently loading\".",
90-
"if(installedChunks[chunkId]) {",
91-
this.indent([
92-
"return installedChunks[chunkId][2];"
93-
]),
94-
"}",
95-
"",
96-
"// setup Promise in chunk cache",
97-
"var promise = new Promise(function(resolve, reject) {",
98-
this.indent([
99-
"installedChunks[chunkId] = [resolve, reject];"
100-
]),
101-
"});",
102-
"installedChunks[chunkId][2] = promise;",
103-
"",
104-
"// start chunk loading",
105-
"var head = document.getElementsByTagName('head')[0];",
106-
this.applyPluginsWaterfall("jsonp-script", "", chunk, hash),
107-
"head.appendChild(script);",
108-
"",
109-
"return promise;"
110-
]);
111-
});
112-
mainTemplate.plugin("require-extensions", function(source, chunk) {
113-
if(chunk.chunks.length === 0) return source;
114-
return this.asString([
115-
source,
116-
"",
117-
"// on error function for async loading",
118-
this.requireFn + ".oe = function(err) { console.error(err); throw err; };"
119-
]);
120-
});
121-
mainTemplate.plugin("bootstrap", function(source, chunk, hash) {
122-
if(chunk.chunks.length > 0) {
123-
var jsonpFunction = this.outputOptions.jsonpFunction;
89+
"}",
90+
"",
91+
"// setup Promise in chunk cache",
92+
"var promise = new Promise(function(resolve, reject) {",
93+
this.indent([
94+
"installedChunks[chunkId] = [resolve, reject];"
95+
]),
96+
"});",
97+
"installedChunks[chunkId][2] = promise;",
98+
"",
99+
"// start chunk loading",
100+
"var head = document.getElementsByTagName('head')[0];",
101+
this.applyPluginsWaterfall("jsonp-script", "", chunk, hash),
102+
"head.appendChild(script);",
103+
"",
104+
"return promise;"
105+
]);
106+
});
107+
mainTemplate.plugin("require-extensions", function(source, chunk) {
108+
if(chunk.chunks.length === 0) return source;
109+
124110
return this.asString([
125111
source,
126112
"",
127-
"// install a JSONP callback for chunk loading",
128-
"var parentJsonpFunction = window[" + JSON.stringify(jsonpFunction) + "];",
129-
"window[" + JSON.stringify(jsonpFunction) + "] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {",
130-
this.indent([
131-
"// add \"moreModules\" to the modules object,",
132-
"// then flag all \"chunkIds\" as loaded and fire callback",
133-
"var moduleId, chunkId, i = 0, resolves = [], result;",
134-
"for(;i < chunkIds.length; i++) {",
135-
this.indent([
136-
"chunkId = chunkIds[i];",
137-
"if(installedChunks[chunkId])",
138-
this.indent("resolves.push(installedChunks[chunkId][0]);"),
139-
"installedChunks[chunkId] = 0;"
140-
]),
141-
"}",
142-
"for(moduleId in moreModules) {",
113+
"// on error function for async loading",
114+
this.requireFn + ".oe = function(err) { console.error(err); throw err; };"
115+
]);
116+
});
117+
mainTemplate.plugin("bootstrap", function(source, chunk, hash) {
118+
if(chunk.chunks.length > 0) {
119+
var jsonpFunction = this.outputOptions.jsonpFunction;
120+
return this.asString([
121+
source,
122+
"",
123+
"// install a JSONP callback for chunk loading",
124+
"var parentJsonpFunction = window[" + JSON.stringify(jsonpFunction) + "];",
125+
"window[" + JSON.stringify(jsonpFunction) + "] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {",
143126
this.indent([
144-
"if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {",
145-
this.indent(this.renderAddModule(hash, chunk, "moduleId", "moreModules[moduleId]")),
146-
"}"
147-
]),
148-
"}",
149-
"if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);",
150-
"while(resolves.length)",
151-
this.indent("resolves.shift()();"),
152-
this.entryPointInChildren(chunk) ? [
153-
"if(executeModules) {",
127+
"// add \"moreModules\" to the modules object,",
128+
"// then flag all \"chunkIds\" as loaded and fire callback",
129+
"var moduleId, chunkId, i = 0, resolves = [], result;",
130+
"for(;i < chunkIds.length; i++) {",
154131
this.indent([
155-
"for(i=0; i < executeModules.length; i++) {",
156-
this.indent("result = " + this.requireFn + "(" + this.requireFn + ".s = executeModules[i]);"),
132+
"chunkId = chunkIds[i];",
133+
"if(installedChunks[chunkId])",
134+
this.indent("resolves.push(installedChunks[chunkId][0]);"),
135+
"installedChunks[chunkId] = 0;"
136+
]),
137+
"}",
138+
"for(moduleId in moreModules) {",
139+
this.indent([
140+
"if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {",
141+
this.indent(this.renderAddModule(hash, chunk, "moduleId", "moreModules[moduleId]")),
157142
"}"
158143
]),
159144
"}",
160-
"return result;",
161-
] : ""
162-
]),
163-
"};"
164-
]);
165-
}
166-
return source;
167-
});
168-
mainTemplate.plugin("hot-bootstrap", function(source, chunk, hash) {
169-
var hotUpdateChunkFilename = this.outputOptions.hotUpdateChunkFilename;
170-
var hotUpdateMainFilename = this.outputOptions.hotUpdateMainFilename;
171-
var hotUpdateFunction = this.outputOptions.hotUpdateFunction;
172-
var currentHotUpdateChunkFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateChunkFilename), {
173-
hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"",
174-
hashWithLength: function(length) {
175-
return "\" + " + this.renderCurrentHashCode(hash, length) + " + \"";
176-
}.bind(this),
177-
chunk: {
178-
id: "\" + chunkId + \""
145+
"if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);",
146+
"while(resolves.length)",
147+
this.indent("resolves.shift()();"),
148+
this.entryPointInChildren(chunk) ? [
149+
"if(executeModules) {",
150+
this.indent([
151+
"for(i=0; i < executeModules.length; i++) {",
152+
this.indent("result = " + this.requireFn + "(" + this.requireFn + ".s = executeModules[i]);"),
153+
"}"
154+
]),
155+
"}",
156+
"return result;",
157+
] : ""
158+
]),
159+
"};"
160+
]);
179161
}
162+
return source;
180163
});
181-
var currentHotUpdateMainFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateMainFilename), {
182-
hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"",
183-
hashWithLength: function(length) {
184-
return "\" + " + this.renderCurrentHashCode(hash, length) + " + \"";
185-
}.bind(this)
164+
mainTemplate.plugin("hot-bootstrap", function(source, chunk, hash) {
165+
const hotUpdateChunkFilename = this.outputOptions.hotUpdateChunkFilename;
166+
const hotUpdateMainFilename = this.outputOptions.hotUpdateMainFilename;
167+
const hotUpdateFunction = this.outputOptions.hotUpdateFunction;
168+
const currentHotUpdateChunkFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateChunkFilename), {
169+
hash: `" + ${this.renderCurrentHashCode(hash)} + "`,
170+
hashWithLength: length => `" + ${this.renderCurrentHashCode(hash, length)} + "`,
171+
chunk: {
172+
id: "\" + chunkId + \""
173+
}
174+
});
175+
const currentHotUpdateMainFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateMainFilename), {
176+
hash: `" + ${this.renderCurrentHashCode(hash)} + "`,
177+
hashWithLength: length => `" + ${this.renderCurrentHashCode(hash, length)} + "`
178+
});
179+
const runtimeCode = Template.getFunctionContent(require("./JsonpMainTemplate.runtime.js"))
180+
.replace(/\/\/\$semicolon/g, ";")
181+
.replace(/\$require\$/g, this.requireFn)
182+
.replace(/\$hotMainFilename\$/g, currentHotUpdateMainFilename)
183+
.replace(/\$hotChunkFilename\$/g, currentHotUpdateChunkFilename)
184+
.replace(/\$hash\$/g, JSON.stringify(hash));
185+
return `${source}
186+
function hotDisposeChunk(chunkId) {
187+
delete installedChunks[chunkId];
188+
}
189+
var parentHotUpdateCallback = this[${JSON.stringify(hotUpdateFunction)}];
190+
this[${JSON.stringify(hotUpdateFunction)}] = ${runtimeCode}`;
186191
});
187-
188-
return source + "\n" +
189-
"function hotDisposeChunk(chunkId) {\n" +
190-
"\tdelete installedChunks[chunkId];\n" +
191-
"}\n" +
192-
"var parentHotUpdateCallback = this[" + JSON.stringify(hotUpdateFunction) + "];\n" +
193-
"this[" + JSON.stringify(hotUpdateFunction) + "] = " + Template.getFunctionContent(require("./JsonpMainTemplate.runtime.js"))
194-
.replace(/\/\/\$semicolon/g, ";")
195-
.replace(/\$require\$/g, this.requireFn)
196-
.replace(/\$hotMainFilename\$/g, currentHotUpdateMainFilename)
197-
.replace(/\$hotChunkFilename\$/g, currentHotUpdateChunkFilename)
198-
.replace(/\$hash\$/g, JSON.stringify(hash));
199-
});
200-
mainTemplate.plugin("hash", function(hash) {
201-
hash.update("jsonp");
202-
hash.update("4");
203-
hash.update(this.outputOptions.filename + "");
204-
hash.update(this.outputOptions.chunkFilename + "");
205-
hash.update(this.outputOptions.jsonpFunction + "");
206-
hash.update(this.outputOptions.hotUpdateFunction + "");
207-
});
208-
};
192+
mainTemplate.plugin("hash", function(hash) {
193+
hash.update("jsonp");
194+
hash.update("4");
195+
hash.update(`${this.outputOptions.filename}`);
196+
hash.update(`${this.outputOptions.chunkFilename}`);
197+
hash.update(`${this.outputOptions.jsonpFunction}`);
198+
hash.update(`${this.outputOptions.hotUpdateFunction}`);
199+
});
200+
}
201+
}
202+
module.exports = JsonpMainTemplatePlugin;

0 commit comments

Comments
 (0)