forked from szrenwei/inline-manifest-webpack-plugin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
119 lines (101 loc) · 4.19 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const sourceMappingURL = require('source-map-url')
const HtmlWebpackPlugin = require('html-webpack-plugin');
class InlineManifestWebpackPlugin {
constructor(name) {
this.name = name || 'runtime';
}
apply(compiler) {
const name = this.name;
compiler.hooks.emit.tap('InlineManifestWebpackPlugin', compilation => {
// get asset name without extension
const chunkName = getAssetName(compilation.chunks, name)
.split('.')
.slice(0, -1)
.join('.');
// exclude it from the emitted assets
Object.keys(compilation.assets).map(key => {
// simple comparison not enough here
// because it can emit the file itself and sourcemap for it
if (key.includes(chunkName)) delete compilation.assets[key];
});
});
compiler.hooks.compilation.tap(
'InlineManifestWebpackPlugin',
compilation => {
const hooks = HtmlWebpackPlugin.getHooks(compilation);
hooks.alterAssetTagGroups.tapAsync(
'InlineManifestWebpackPlugin',
function (data, cb) {
const manifestAssetName = getAssetName(compilation.chunks, name);
if (manifestAssetName) {
data.headTags = inlineWhenMatched(
compilation,
data.headTags,
manifestAssetName
);
data.bodyTags = inlineWhenMatched(
compilation,
data.bodyTags,
manifestAssetName
);
}
cb(null, data);
}
);
hooks.beforeAssetTagGeneration.tapAsync(
'InlineManifestWebpackPlugin',
function (htmlPluginData, cb) {
const runtime = [];
const assets = htmlPluginData.assets;
const manifestAssetName = getAssetName(compilation.chunks, name);
if (
manifestAssetName &&
htmlPluginData.plugin.options.inject === false
) {
runtime.push('<script>');
runtime.push(
sourceMappingURL.removeFrom(
compilation.assets[manifestAssetName].source()
)
);
runtime.push('</script>');
const runtimeIndex = assets.js.indexOf(
assets.publicPath + manifestAssetName
);
if (runtimeIndex >= 0) {
assets.js.splice(runtimeIndex, 1);
delete assets.chunks[name];
}
}
assets.runtime = runtime.join('');
cb(null, htmlPluginData);
}
);
}
);
}
}
function getAssetName(chunks, chunkName) {
return (chunks.filter(({ name }) => name === chunkName)[0] || { files: [] }).files[0];
}
function inlineWhenMatched(compilation, scripts, manifestAssetName) {
return scripts.map(function (script) {
const isManifestScript =
script.tagName === 'script' &&
script.attributes.src.indexOf(manifestAssetName) >= 0;
if (isManifestScript) {
return {
tagName: 'script',
closeTag: true,
attributes: {
type: 'text/javascript',
},
innerHTML: sourceMappingURL.removeFrom(
compilation.assets[manifestAssetName].source()
),
};
}
return script;
});
}
module.exports = InlineManifestWebpackPlugin