[6a3a178] | 1 | "use strict";
|
---|
| 2 |
|
---|
| 3 | Object.defineProperty(exports, "__esModule", {
|
---|
| 4 | value: true
|
---|
| 5 | });
|
---|
| 6 | exports.default = void 0;
|
---|
| 7 |
|
---|
| 8 | var os = _interopRequireWildcard(require("os"));
|
---|
| 9 |
|
---|
| 10 | var _sourceMap = require("source-map");
|
---|
| 11 |
|
---|
| 12 | var _schemaUtils = require("schema-utils");
|
---|
| 13 |
|
---|
| 14 | var _serializeJavascript = _interopRequireDefault(require("serialize-javascript"));
|
---|
| 15 |
|
---|
| 16 | var _pLimit = _interopRequireDefault(require("p-limit"));
|
---|
| 17 |
|
---|
| 18 | var _jestWorker = require("jest-worker");
|
---|
| 19 |
|
---|
| 20 | var _utils = require("./utils");
|
---|
| 21 |
|
---|
| 22 | var schema = _interopRequireWildcard(require("./options.json"));
|
---|
| 23 |
|
---|
| 24 | var _minify = require("./minify");
|
---|
| 25 |
|
---|
| 26 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
---|
| 27 |
|
---|
| 28 | function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
---|
| 29 |
|
---|
| 30 | function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
---|
| 31 |
|
---|
| 32 | const warningRegex = /\s.+:+([0-9]+):+([0-9]+)/;
|
---|
| 33 |
|
---|
| 34 | class CssMinimizerPlugin {
|
---|
| 35 | constructor(options = {}) {
|
---|
| 36 | (0, _schemaUtils.validate)(schema, options, {
|
---|
| 37 | name: 'Css Minimizer Plugin',
|
---|
| 38 | baseDataPath: 'options'
|
---|
| 39 | });
|
---|
| 40 | const {
|
---|
| 41 | minify = _utils.cssnanoMinify,
|
---|
| 42 | minimizerOptions,
|
---|
| 43 | test = /\.css(\?.*)?$/i,
|
---|
| 44 | warningsFilter = () => true,
|
---|
| 45 | parallel = true,
|
---|
| 46 | include,
|
---|
| 47 | exclude
|
---|
| 48 | } = options;
|
---|
| 49 | this.options = {
|
---|
| 50 | test,
|
---|
| 51 | warningsFilter,
|
---|
| 52 | parallel,
|
---|
| 53 | include,
|
---|
| 54 | exclude,
|
---|
| 55 | minify,
|
---|
| 56 | minimizerOptions
|
---|
| 57 | };
|
---|
| 58 | }
|
---|
| 59 |
|
---|
| 60 | static isSourceMap(input) {
|
---|
| 61 | // All required options for `new SourceMapConsumer(...options)`
|
---|
| 62 | // https://github.com/mozilla/source-map#new-sourcemapconsumerrawsourcemap
|
---|
| 63 | return Boolean(input && input.version && input.sources && Array.isArray(input.sources) && typeof input.mappings === 'string');
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | static buildError(error, name, requestShortener, sourceMap) {
|
---|
| 67 | let builtError;
|
---|
| 68 |
|
---|
| 69 | if (error.line) {
|
---|
| 70 | const original = sourceMap && sourceMap.originalPositionFor({
|
---|
| 71 | line: error.line,
|
---|
| 72 | column: error.column
|
---|
| 73 | });
|
---|
| 74 |
|
---|
| 75 | if (original && original.source && requestShortener) {
|
---|
| 76 | builtError = new Error(`${name} from Css Minimizer Webpack Plugin\n${error.message} [${requestShortener.shorten(original.source)}:${original.line},${original.column}][${name}:${error.line},${error.column}]${error.stack ? `\n${error.stack.split('\n').slice(1).join('\n')}` : ''}`);
|
---|
| 77 | builtError.file = name;
|
---|
| 78 | return builtError;
|
---|
| 79 | }
|
---|
| 80 |
|
---|
| 81 | builtError = new Error(`${name} from Css Minimizer \n${error.message} [${name}:${error.line},${error.column}]${error.stack ? `\n${error.stack.split('\n').slice(1).join('\n')}` : ''}`);
|
---|
| 82 | builtError.file = name;
|
---|
| 83 | return builtError;
|
---|
| 84 | }
|
---|
| 85 |
|
---|
| 86 | if (error.stack) {
|
---|
| 87 | builtError = new Error(`${name} from Css Minimizer\n${error.stack}`);
|
---|
| 88 | builtError.file = name;
|
---|
| 89 | return builtError;
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 | builtError = new Error(`${name} from Css Minimizer\n${error.message}`);
|
---|
| 93 | builtError.file = name;
|
---|
| 94 | return builtError;
|
---|
| 95 | }
|
---|
| 96 |
|
---|
| 97 | static buildWarning(warning, file, sourceMap, requestShortener, warningsFilter) {
|
---|
| 98 | let warningMessage = warning;
|
---|
| 99 | let locationMessage = '';
|
---|
| 100 | let source;
|
---|
| 101 |
|
---|
| 102 | if (sourceMap) {
|
---|
| 103 | const match = warningRegex.exec(warning);
|
---|
| 104 |
|
---|
| 105 | if (match) {
|
---|
| 106 | const line = +match[1];
|
---|
| 107 | const column = +match[2];
|
---|
| 108 | const original = sourceMap.originalPositionFor({
|
---|
| 109 | line,
|
---|
| 110 | column
|
---|
| 111 | });
|
---|
| 112 |
|
---|
| 113 | if (original && original.source && original.source !== file && requestShortener) {
|
---|
| 114 | ({
|
---|
| 115 | source
|
---|
| 116 | } = original);
|
---|
| 117 | warningMessage = `${warningMessage.replace(warningRegex, '')}`;
|
---|
| 118 | locationMessage = `${requestShortener.shorten(original.source)}:${original.line}:${original.column}`;
|
---|
| 119 | }
|
---|
| 120 | }
|
---|
| 121 | }
|
---|
| 122 |
|
---|
| 123 | if (warningsFilter && !warningsFilter(warning, file, source)) {
|
---|
| 124 | return null;
|
---|
| 125 | }
|
---|
| 126 |
|
---|
| 127 | return `Css Minimizer Plugin: ${warningMessage} ${locationMessage}`;
|
---|
| 128 | }
|
---|
| 129 |
|
---|
| 130 | static getAvailableNumberOfCores(parallel) {
|
---|
| 131 | // In some cases cpus() returns undefined
|
---|
| 132 | // https://github.com/nodejs/node/issues/19022
|
---|
| 133 | const cpus = os.cpus() || {
|
---|
| 134 | length: 1
|
---|
| 135 | };
|
---|
| 136 | return parallel === true ? cpus.length - 1 : Math.min(Number(parallel) || 0, cpus.length - 1);
|
---|
| 137 | }
|
---|
| 138 |
|
---|
| 139 | async optimize(compiler, compilation, assets, optimizeOptions) {
|
---|
| 140 | const cache = compilation.getCache('CssMinimizerWebpackPlugin');
|
---|
| 141 | let numberOfAssetsForMinify = 0;
|
---|
| 142 | const assetsForMinify = await Promise.all(Object.keys(typeof assets === 'undefined' ? compilation.assets : assets).filter(name => {
|
---|
| 143 | const {
|
---|
| 144 | info
|
---|
| 145 | } = compilation.getAsset(name);
|
---|
| 146 |
|
---|
| 147 | if ( // Skip double minimize assets from child compilation
|
---|
| 148 | info.minimized) {
|
---|
| 149 | return false;
|
---|
| 150 | }
|
---|
| 151 |
|
---|
| 152 | if (!compiler.webpack.ModuleFilenameHelpers.matchObject.bind( // eslint-disable-next-line no-undefined
|
---|
| 153 | undefined, this.options)(name)) {
|
---|
| 154 | return false;
|
---|
| 155 | }
|
---|
| 156 |
|
---|
| 157 | return true;
|
---|
| 158 | }).map(async name => {
|
---|
| 159 | const {
|
---|
| 160 | info,
|
---|
| 161 | source
|
---|
| 162 | } = compilation.getAsset(name);
|
---|
| 163 | const eTag = cache.getLazyHashedEtag(source);
|
---|
| 164 | const cacheItem = cache.getItemCache(name, eTag);
|
---|
| 165 | const output = await cacheItem.getPromise();
|
---|
| 166 |
|
---|
| 167 | if (!output) {
|
---|
| 168 | numberOfAssetsForMinify += 1;
|
---|
| 169 | }
|
---|
| 170 |
|
---|
| 171 | return {
|
---|
| 172 | name,
|
---|
| 173 | info,
|
---|
| 174 | inputSource: source,
|
---|
| 175 | output,
|
---|
| 176 | cacheItem
|
---|
| 177 | };
|
---|
| 178 | }));
|
---|
| 179 | let getWorker;
|
---|
| 180 | let initializedWorker;
|
---|
| 181 | let numberOfWorkers;
|
---|
| 182 |
|
---|
| 183 | if (optimizeOptions.availableNumberOfCores > 0) {
|
---|
| 184 | // Do not create unnecessary workers when the number of files is less than the available cores, it saves memory
|
---|
| 185 | numberOfWorkers = Math.min(numberOfAssetsForMinify, optimizeOptions.availableNumberOfCores);
|
---|
| 186 |
|
---|
| 187 | getWorker = () => {
|
---|
| 188 | if (initializedWorker) {
|
---|
| 189 | return initializedWorker;
|
---|
| 190 | }
|
---|
| 191 |
|
---|
| 192 | initializedWorker = new _jestWorker.Worker(require.resolve('./minify'), {
|
---|
| 193 | numWorkers: numberOfWorkers,
|
---|
| 194 | enableWorkerThreads: true
|
---|
| 195 | }); // https://github.com/facebook/jest/issues/8872#issuecomment-524822081
|
---|
| 196 |
|
---|
| 197 | const workerStdout = initializedWorker.getStdout();
|
---|
| 198 |
|
---|
| 199 | if (workerStdout) {
|
---|
| 200 | workerStdout.on('data', chunk => process.stdout.write(chunk));
|
---|
| 201 | }
|
---|
| 202 |
|
---|
| 203 | const workerStderr = initializedWorker.getStderr();
|
---|
| 204 |
|
---|
| 205 | if (workerStderr) {
|
---|
| 206 | workerStderr.on('data', chunk => process.stderr.write(chunk));
|
---|
| 207 | }
|
---|
| 208 |
|
---|
| 209 | return initializedWorker;
|
---|
| 210 | };
|
---|
| 211 | }
|
---|
| 212 |
|
---|
| 213 | const limit = (0, _pLimit.default)(getWorker && numberOfAssetsForMinify > 0 ? numberOfWorkers : Infinity);
|
---|
| 214 | const {
|
---|
| 215 | SourceMapSource,
|
---|
| 216 | RawSource
|
---|
| 217 | } = compiler.webpack.sources;
|
---|
| 218 | const scheduledTasks = [];
|
---|
| 219 |
|
---|
| 220 | for (const asset of assetsForMinify) {
|
---|
| 221 | scheduledTasks.push(limit(async () => {
|
---|
| 222 | const {
|
---|
| 223 | name,
|
---|
| 224 | inputSource,
|
---|
| 225 | cacheItem
|
---|
| 226 | } = asset;
|
---|
| 227 | let {
|
---|
| 228 | output
|
---|
| 229 | } = asset;
|
---|
| 230 |
|
---|
| 231 | if (!output) {
|
---|
| 232 | let input;
|
---|
| 233 | let inputSourceMap;
|
---|
| 234 | const {
|
---|
| 235 | source: sourceFromInputSource,
|
---|
| 236 | map
|
---|
| 237 | } = inputSource.sourceAndMap();
|
---|
| 238 | input = sourceFromInputSource;
|
---|
| 239 |
|
---|
| 240 | if (map) {
|
---|
| 241 | if (CssMinimizerPlugin.isSourceMap(map)) {
|
---|
| 242 | inputSourceMap = map;
|
---|
| 243 | } else {
|
---|
| 244 | inputSourceMap = map;
|
---|
| 245 | compilation.warnings.push(new Error(`${name} contains invalid source map`));
|
---|
| 246 | }
|
---|
| 247 | }
|
---|
| 248 |
|
---|
| 249 | if (Buffer.isBuffer(input)) {
|
---|
| 250 | input = input.toString();
|
---|
| 251 | }
|
---|
| 252 |
|
---|
| 253 | const options = {
|
---|
| 254 | name,
|
---|
| 255 | input,
|
---|
| 256 | inputSourceMap,
|
---|
| 257 | minify: this.options.minify,
|
---|
| 258 | minifyOptions: this.options.minimizerOptions
|
---|
| 259 | };
|
---|
| 260 |
|
---|
| 261 | try {
|
---|
| 262 | output = await (getWorker ? getWorker().transform((0, _serializeJavascript.default)(options)) : (0, _minify.minify)(options));
|
---|
| 263 | } catch (error) {
|
---|
| 264 | compilation.errors.push(CssMinimizerPlugin.buildError(error, name, compilation.requestShortener, inputSourceMap && CssMinimizerPlugin.isSourceMap(inputSourceMap) ? new _sourceMap.SourceMapConsumer(inputSourceMap) : null));
|
---|
| 265 | return;
|
---|
| 266 | }
|
---|
| 267 |
|
---|
| 268 | if (output.map) {
|
---|
| 269 | output.source = new SourceMapSource(output.code, name, output.map, input, inputSourceMap, true);
|
---|
| 270 | } else {
|
---|
| 271 | output.source = new RawSource(output.code);
|
---|
| 272 | }
|
---|
| 273 |
|
---|
| 274 | if (output.warnings && output.warnings.length > 0) {
|
---|
| 275 | output.warnings = output.warnings.map(warning => CssMinimizerPlugin.buildWarning(warning, name, inputSourceMap && CssMinimizerPlugin.isSourceMap(inputSourceMap) ? new _sourceMap.SourceMapConsumer(inputSourceMap) : null, compilation.requestShortener, this.options.warningsFilter)).filter(Boolean);
|
---|
| 276 | }
|
---|
| 277 |
|
---|
| 278 | await cacheItem.storePromise({
|
---|
| 279 | source: output.source,
|
---|
| 280 | warnings: output.warnings
|
---|
| 281 | });
|
---|
| 282 | }
|
---|
| 283 |
|
---|
| 284 | if (output.warnings && output.warnings.length > 0) {
|
---|
| 285 | output.warnings.forEach(warning => {
|
---|
| 286 | const Warning = class Warning extends Error {
|
---|
| 287 | constructor(message) {
|
---|
| 288 | super(message);
|
---|
| 289 | this.name = 'Warning';
|
---|
| 290 | this.hideStack = true;
|
---|
| 291 | this.file = name;
|
---|
| 292 | }
|
---|
| 293 |
|
---|
| 294 | };
|
---|
| 295 | compilation.warnings.push(new Warning(warning));
|
---|
| 296 | });
|
---|
| 297 | }
|
---|
| 298 |
|
---|
| 299 | const newInfo = {
|
---|
| 300 | minimized: true
|
---|
| 301 | };
|
---|
| 302 | const {
|
---|
| 303 | source
|
---|
| 304 | } = output;
|
---|
| 305 | compilation.updateAsset(name, source, newInfo);
|
---|
| 306 | }));
|
---|
| 307 | }
|
---|
| 308 |
|
---|
| 309 | const result = await Promise.all(scheduledTasks);
|
---|
| 310 |
|
---|
| 311 | if (initializedWorker) {
|
---|
| 312 | await initializedWorker.end();
|
---|
| 313 | }
|
---|
| 314 |
|
---|
| 315 | return result;
|
---|
| 316 | }
|
---|
| 317 |
|
---|
| 318 | apply(compiler) {
|
---|
| 319 | const pluginName = this.constructor.name;
|
---|
| 320 | const availableNumberOfCores = CssMinimizerPlugin.getAvailableNumberOfCores(this.options.parallel);
|
---|
| 321 | compiler.hooks.compilation.tap(pluginName, compilation => {
|
---|
| 322 | compilation.hooks.processAssets.tapPromise({
|
---|
| 323 | name: pluginName,
|
---|
| 324 | stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,
|
---|
| 325 | additionalAssets: true
|
---|
| 326 | }, assets => this.optimize(compiler, compilation, assets, {
|
---|
| 327 | availableNumberOfCores
|
---|
| 328 | }));
|
---|
| 329 | compilation.hooks.statsPrinter.tap(pluginName, stats => {
|
---|
| 330 | stats.hooks.print.for('asset.info.minimized').tap('css-minimizer-webpack-plugin', (minimized, {
|
---|
| 331 | green,
|
---|
| 332 | formatFlag
|
---|
| 333 | }) => // eslint-disable-next-line no-undefined
|
---|
| 334 | minimized ? green(formatFlag('minimized')) : '');
|
---|
| 335 | });
|
---|
| 336 | });
|
---|
| 337 | }
|
---|
| 338 |
|
---|
| 339 | }
|
---|
| 340 |
|
---|
| 341 | CssMinimizerPlugin.cssnanoMinify = _utils.cssnanoMinify;
|
---|
| 342 | CssMinimizerPlugin.cssoMinify = _utils.cssoMinify;
|
---|
| 343 | CssMinimizerPlugin.cleanCssMinify = _utils.cleanCssMinify;
|
---|
| 344 | var _default = CssMinimizerPlugin;
|
---|
| 345 | exports.default = _default; |
---|