This repository has been archived by the owner on Sep 21, 2023. It is now read-only.
forked from levp/wrapper-webpack-plugin
-
Notifications
You must be signed in to change notification settings - Fork 2
/
wrapper-webpack-plugin.js
87 lines (76 loc) · 2.96 KB
/
wrapper-webpack-plugin.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
/* fix based on
* https://github.com/levp/wrapper-webpack-plugin/issues/11#issuecomment-708215938
* and https://github.com/webpack/webpack-sources/issues/92#issuecomment-709601572
*/
'use strict';
const ModuleFilenameHelpers = require("webpack/lib/ModuleFilenameHelpers");
var offsetLines = require('offset-sourcemap-lines');
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 header = this.header;
const footer = this.footer;
const tester = {test: this.test};
compiler.hooks.thisCompilation.tap('WrapperPlugin', (compilation) => {
// webpack 5: use new processAssets
compilation.hooks.processAssets.tap(
{
name: 'WrapperPlugin',
stage: compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
},
(chunks) => wrapChunks(compilation, chunks),
);
});
function wrapFile(compilation, fileName, chunkHash) {
const headerContent = (typeof header === 'function') ? header(fileName, chunkHash) : header;
const footerContent = (typeof footer === 'function') ? footer(fileName, chunkHash) : footer;
const {source, map} = compilation.getAsset(fileName).source.sourceAndMap();
const wrappedSource = new compiler.webpack.sources.ConcatSource(
String(headerContent),
source.toString(),
String(footerContent),
);
if (map) {
const offset = headerContent.split(/\r\n|\r|\n/).length - 1;
const offsetMap = offsetLines(map, offset);
const sourceWithMap = new compiler.webpack.sources.SourceMapSource(
wrappedSource.source().toString(),
fileName,
offsetMap,
source,
map,
false
);
compilation.updateAsset(fileName, sourceWithMap);
} else {
compilation.updateAsset(fileName, wrappedSource);
}
}
function wrapChunks(compilation, chunks) {
Object.keys(chunks).forEach(fileName => {
if (ModuleFilenameHelpers.matchObject(tester, fileName)) {
wrapFile(compilation, fileName, compilation.hash);
}
});
}
}
}
module.exports = WrapperPlugin;