-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathoptimize-css-webpack-plugin.js
90 lines (90 loc) · 3.48 KB
/
optimize-css-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
88
89
90
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
const cssNano = require("cssnano");
const webpack_sources_1 = require("webpack-sources");
function hook(compiler, action) {
compiler.hooks.compilation.tap('optimize-css-webpack-plugin', (compilation) => {
compilation.hooks.optimizeChunkAssets.tapPromise('optimize-css-webpack-plugin', chunks => action(compilation, chunks));
});
}
class OptimizeCssWebpackPlugin {
constructor(options) {
this._options = {
sourceMap: false,
test: file => file.endsWith('.css'),
...options,
};
}
apply(compiler) {
hook(compiler, (compilation, chunks) => {
const files = [...compilation.additionalChunkAssets];
chunks.forEach(chunk => {
if (chunk.files && chunk.files.length > 0) {
files.push(...chunk.files);
}
});
const actions = files
.filter(file => this._options.test(file))
.map(async (file) => {
const asset = compilation.assets[file];
if (!asset) {
return;
}
let content;
// tslint:disable-next-line: no-any
let map;
if (this._options.sourceMap && asset.sourceAndMap) {
const sourceAndMap = asset.sourceAndMap();
content = sourceAndMap.source;
map = sourceAndMap.map;
}
else {
content = asset.source();
}
if (content.length === 0) {
return;
}
const cssNanoOptions = {
preset: ['default', {
// Disable SVG optimization, as this can cause optimizations which are not compatible in all browsers.
svgo: false,
}],
};
const postCssOptions = {
from: file,
map: map && { annotation: false, prev: map },
};
const output = await new Promise((resolve, reject) => {
// the last parameter is not in the typings
// tslint:disable-next-line: no-any
cssNano.process(content, postCssOptions, cssNanoOptions)
.then(resolve)
.catch(reject);
});
const warnings = output.warnings();
if (warnings.length) {
compilation.warnings.push(...warnings.map(({ text }) => text));
}
let newSource;
if (output.map) {
newSource = new webpack_sources_1.SourceMapSource(output.css, file,
// tslint:disable-next-line: no-any
output.map.toString(), content, map);
}
else {
newSource = new webpack_sources_1.RawSource(output.css);
}
compilation.assets[file] = newSource;
});
return Promise.all(actions);
});
}
}
exports.OptimizeCssWebpackPlugin = OptimizeCssWebpackPlugin;