-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathwrapper-webpack-plugin.js
More file actions
85 lines (73 loc) · 2.72 KB
/
wrapper-webpack-plugin.js
File metadata and controls
85 lines (73 loc) · 2.72 KB
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
'use strict';
const ModuleFilenameHelpers = require("webpack/lib/ModuleFilenameHelpers");
class WrapperPlugin {
/**
* @param {Object} args
* @param {string | Function} [args.header] Text that will be prepended to an output file.
* @param {string | Function} [args.footer] Text that will be appended to an output file.
* @param {string | RegExp} [args.test] Tested against output file names to check if they should be affected by this
* plugin.
* @param {boolean} [args.afterOptimizations=false] Indicating whether this plugin should be activated before
* (`false`) or after (`true`) the optimization stage. Example use case: Set this to true if you want to avoid
* minification from affecting the text added by this plugin.
*/
constructor(args) {
if (typeof args !== 'object') {
throw new TypeError('Argument "args" must be an object.');
}
this.header = args.hasOwnProperty('header') ? args.header : '';
this.footer = args.hasOwnProperty('footer') ? args.footer : '';
this.afterOptimizations = args.hasOwnProperty('afterOptimizations') ? !!args.afterOptimizations : false;
this.test = args.hasOwnProperty('test') ? args.test : '';
}
apply(compiler) {
const ConcatSource = getSourceConcatenator(compiler);
const header = this.header;
const footer = this.footer;
const tester = {test: this.test};
compiler.hooks.compilation.tap('WrapperPlugin', (compilation) => {
if (this.afterOptimizations) {
compilation.hooks.afterOptimizeChunkAssets.tap('WrapperPlugin', (chunks) => {
wrapChunks(compilation, chunks, footer, header);
});
} else {
compilation.hooks.optimizeChunkAssets.tapAsync('WrapperPlugin', (chunks, done) => {
wrapChunks(compilation, chunks, footer, header);
done();
});
}
});
function wrapFile(compilation, fileName, chunkHash) {
const headerContent = (typeof header === 'function') ? header(fileName, chunkHash) : header;
const footerContent = (typeof footer === 'function') ? footer(fileName, chunkHash) : footer;
compilation.assets[fileName] = new ConcatSource(
String(headerContent),
compilation.assets[fileName],
String(footerContent),
);
}
function wrapChunks(compilation, chunks) {
for (const chunk of chunks) {
const args = {
hash: compilation.hash,
chunkhash: chunk.hash,
};
for (const fileName of chunk.files) {
if (ModuleFilenameHelpers.matchObject(tester, fileName)) {
wrapFile(compilation, fileName, args);
}
}
}
} // wrapChunks
}
}
module.exports = WrapperPlugin;
function getSourceConcatenator(compiler) {
const webpack = compiler.webpack;
if (webpack) {
// webpack v5
return webpack.sources.ConcatSource;
}
// webpack v4
return require("webpack-sources").ConcatSource;
}