-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
105 lines (103 loc) · 3.83 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
"use strict";
const Template = require("webpack/lib/Template");
class HippyJsonpTemplatePlugin {
apply(compiler) {
compiler.hooks.make.tapAsync("HippyJsonpTemplatePlugin", (compilation, callback) => {
const tapsOfRequireEnsuer = compilation.mainTemplate.hooks.requireEnsure.taps;
// console.log("=====HippyJsonpTemplatePlugin======");
for (let i = 0; i < tapsOfRequireEnsuer.length; i++) {
if (tapsOfRequireEnsuer[i].name === "JsonpMainTemplatePlugin load") {
tapsOfRequireEnsuer.splice(i, 1);
compilation.mainTemplate.hooks.requireEnsure.tap(
"JsonpMainTemplatePlugin load",
(source, chunk, hash) => {
const chunkLoadTimeout = compilation.mainTemplate.outputOptions.chunkLoadTimeout;
return Template.asString([
source,
"",
"// JSONP chunk loading for javascript",
"",
"var installedChunkData = installedChunks[chunkId];",
'if(installedChunkData !== 0) { // 0 means "already installed".',
Template.indent([
"",
'// a Promise means "currently loading".',
"if(installedChunkData) {",
Template.indent(["promises.push(installedChunkData[2]);"]),
"} else {",
Template.indent([
"// setup Promise in chunk cache",
"var promise = new Promise(function(resolve, reject) {",
Template.indent([
"installedChunkData = installedChunks[chunkId] = [resolve, reject];"
]),
"});",
"promises.push(installedChunkData[2] = promise);",
"",
"// start chunk loading",
// "function runCode(code) { (0, eval)('this').eval(code); }",
"function runCode(code) { new Function(code)() }",
"var script = {}",
"var onScriptComplete;",
`script.timeout = ${chunkLoadTimeout / 1000};`,
"script.src = jsonpScriptSrc(chunkId);",
"console.log('请求地址:',script.src)",
"fetch(script.src).then(res => {",
Template.indent([
// "console.info(res,'返回成功后数据')",
"runCode(res.body);",
"script.onload();"
]),
"}).catch(err => {",
// "console.error(err,'返回失败后数据')",
Template.indent([
"script.onerror({ type: 'error', src: err.userInfo && err.userInfo.NSErrorFailingURLStringKey || err})",
]),
"})",
"// create error before stack unwound to get useful stacktrace later",
"var error = new Error();",
"onScriptComplete = function (event) {",
Template.indent([
"// avoid mem leaks in IE.",
"script.onerror = script.onload = null;",
"clearTimeout(timeout);",
"var chunk = installedChunks[chunkId];",
"if(chunk !== 0) {",
Template.indent([
"if(chunk) {",
Template.indent([
"var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
"var realSrc = event.src",
"error.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
"error.name = 'ChunkLoadError';",
"error.type = errorType;",
"error.request = realSrc;",
"chunk[1](error);"
]),
"}",
"installedChunks[chunkId] = undefined;"
]),
"}"
]),
"};",
"var timeout = setTimeout(function(){",
Template.indent([
"onScriptComplete({ type: 'timeout', target: script });"
]),
`}, ${chunkLoadTimeout});`,
"script.onerror = script.onload = onScriptComplete;"
]),
"}"
]),
"}"
]);
}
);
break;
}
}
callback(null, compilation);
});
}
}
module.exports = HippyJsonpTemplatePlugin;