forked from pallyoung/webpack-entrypoints-plugin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
99 lines (91 loc) · 3.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
const name = 'WebpackEntrypointsPlugin'
const fs = require('fs');
const { dirname, relative, resolve } = require('path');
const schema = require('./plugin.json');
const { validate } = require('schema-utils');
const webpack = require('webpack');
const { RawSource } = webpack.sources || require('webpack-sources');
class WebpackEntrypointsPlugin {
constructor(options) {
validate(schema, options, { name: 'Entrypoints Plugin' });
this.path = options.path || 'entrypoints.json';
this.change = options.change;
this.merge = options.merge || false;
this.writeToFileEmit = options.writeToFileEmit || false;
}
apply(compiler) {
const emit = (compilation) => {
const stats = compilation.getStats();
const chunkOnlyConfig = {
assets: true,
cached: false,
children: true,
chunks: true,
chunkModules: false,
chunkOrigins: false,
errorDetails: false,
hash: false,
modules: false,
reasons: false,
source: false,
timings: false,
version: false
};
const statsObject = stats.toJson(chunkOnlyConfig);
const entrypoints = statsObject.entrypoints;
const path = resolve(compiler.options.output.path, this.path);
let data = {};
if (this.merge && fs.existsSync(path)) {
data = JSON.parse(fs.readFileSync(path).toString());
}
for (let en in entrypoints) {
/* Augment entrypoint chunks with more information from other stats */
entrypoints[en].chunks = entrypoints[en].chunks.map(chunkId => {
const chunk = statsObject.chunks.find(chunk => chunk.id === chunkId);
if (!chunk) {
return chunkId;
}
return {
id: chunkId,
files: chunk.files,
size: chunk.size,
}
})
/* Augment entrypoint assets with more information from other stats,
particularly as at the time in the compilation that we run the entrypoint
stats don't include asset sizes.
*/
entrypoints[en].assets = entrypoints[en].assets.map(entrypointAsset => {
const assetStats = statsObject.assets.find(asset => asset.name === entrypointAsset.name);
if (!assetStats) {
return assetStats;
}
return {
name: assetStats.name,
size: assetStats.size,
}
})
data[en] = {
chunks: entrypoints[en].chunks,
assets: entrypoints[en].assets,
}
}
const output = JSON.stringify(data, null, ' ');
const assetId = relative(compiler.options.output.path, path);
compilation.emitAsset(assetId, new RawSource(output));
if (this.writeToFileEmit) {
fs.mkdirSync(dirname(path), { recursive: true });
fs.writeFileSync(path, output);
}
this.change && this.change(data);
};
if (webpack.version.startsWith('4')) {
compiler.hooks.emit.tap(name, emit);
} else {
compiler.hooks.thisCompilation.tap(name, (compilation) => {
compilation.hooks.afterProcessAssets.tap(name, () => emit(compilation));
});
}
}
}
module.exports = WebpackEntrypointsPlugin;