1 | "use strict";
|
2 |
|
3 | const {
|
4 | validate
|
5 | } = require("schema-utils");
|
6 | const schema = require("./options.json");
|
7 | const {
|
8 | minify
|
9 | } = require("./minify");
|
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 | class JsonMinimizerPlugin {
|
50 | |
51 |
|
52 |
|
53 | constructor(options = {}) {
|
54 | validate( schema, options, {
|
55 | name: "Json Minimizer Plugin",
|
56 | baseDataPath: "options"
|
57 | });
|
58 | const {
|
59 | minimizerOptions = {},
|
60 | test = /\.json(\?.*)?$/i,
|
61 | include,
|
62 | exclude
|
63 | } = options;
|
64 |
|
65 | |
66 |
|
67 |
|
68 |
|
69 | this.options = {
|
70 | test,
|
71 | include,
|
72 | exclude,
|
73 | minimizerOptions
|
74 | };
|
75 | }
|
76 |
|
77 | |
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 | static buildError(error, file, context) {
|
84 | return new Error(`"${file}" in "${context}" from Json Minimizer:\n${error}`);
|
85 | }
|
86 |
|
87 | |
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 | async optimize(compiler, compilation, assets) {
|
95 | const cache = compilation.getCache("JsonMinimizerWebpackPlugin");
|
96 | const assetsForMinify = await Promise.all(Object.keys(assets).filter(name => {
|
97 | const {
|
98 | info
|
99 | } = compilation.getAsset(name);
|
100 |
|
101 |
|
102 | if (info.minimized) {
|
103 | return false;
|
104 | }
|
105 | if (!compiler.webpack.ModuleFilenameHelpers.matchObject.bind(
|
106 |
|
107 | undefined, this.options)(name)) {
|
108 | return false;
|
109 | }
|
110 | return true;
|
111 | }).map(async name => {
|
112 | const {
|
113 | info,
|
114 | source
|
115 | } =
|
116 | compilation.getAsset(name);
|
117 | const eTag = cache.getLazyHashedEtag(source);
|
118 | const cacheItem = cache.getItemCache(name, eTag);
|
119 | const output = await cacheItem.getPromise();
|
120 | return {
|
121 | name,
|
122 | info,
|
123 | inputSource: source,
|
124 | output,
|
125 | cacheItem
|
126 | };
|
127 | }));
|
128 | const {
|
129 | RawSource
|
130 | } = compiler.webpack.sources;
|
131 | const scheduledTasks = [];
|
132 | for (const asset of assetsForMinify) {
|
133 | scheduledTasks.push((async () => {
|
134 | const {
|
135 | name,
|
136 | inputSource,
|
137 | cacheItem
|
138 | } = asset;
|
139 | let {
|
140 | output
|
141 | } = asset;
|
142 | let input;
|
143 | const sourceFromInputSource = inputSource.source();
|
144 | if (!output) {
|
145 | input = sourceFromInputSource;
|
146 | if (Buffer.isBuffer(input)) {
|
147 | input = input.toString();
|
148 | }
|
149 |
|
150 | |
151 |
|
152 |
|
153 | const options = {
|
154 | input,
|
155 | minimizerOptions: this.options.minimizerOptions
|
156 | };
|
157 | try {
|
158 | output = await minify(options);
|
159 | } catch (error) {
|
160 | compilation.errors.push(
|
161 | JsonMinimizerPlugin.buildError(error, name, compiler.context));
|
162 | return;
|
163 | }
|
164 | output.source = new RawSource(output.code);
|
165 | await cacheItem.storePromise({
|
166 | source: output.source
|
167 | });
|
168 | }
|
169 | const newInfo = {
|
170 | minimized: true
|
171 | };
|
172 | const {
|
173 | source
|
174 | } = output;
|
175 | compilation.updateAsset(name, source, newInfo);
|
176 | })());
|
177 | }
|
178 | Promise.all(scheduledTasks);
|
179 | }
|
180 |
|
181 | |
182 |
|
183 |
|
184 |
|
185 | apply(compiler) {
|
186 | const pluginName = this.constructor.name;
|
187 | compiler.hooks.compilation.tap(pluginName, compilation => {
|
188 | compilation.hooks.processAssets.tapPromise({
|
189 | name: pluginName,
|
190 | stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,
|
191 | additionalAssets: true
|
192 | }, assets => this.optimize(compiler, compilation, assets));
|
193 | compilation.hooks.statsPrinter.tap(pluginName, stats => {
|
194 | stats.hooks.print.for("asset.info.minimized").tap("json-minimizer-webpack-plugin", (minimized, {
|
195 | green,
|
196 | formatFlag
|
197 | }) => minimized ? green( formatFlag("minimized")) : "");
|
198 | });
|
199 | });
|
200 | }
|
201 | }
|
202 | module.exports = JsonMinimizerPlugin; |
\ | No newline at end of file |