UNPKG

csso-webpack-plugin

Version:

CSSO minification files to serve your webpack bundles

210 lines (159 loc) 6.25 kB
"use strict"; exports.__esModule = true; exports.default = void 0; require("core-js/modules/es.string.replace.js"); require("core-js/modules/es.promise.js"); require("core-js/modules/es.array.iterator.js"); require("core-js/modules/web.url.to-json.js"); var _path = _interopRequireDefault(require("path")); var _csso = _interopRequireDefault(require("csso")); var _RawSource = _interopRequireDefault(require("webpack-sources/lib/RawSource")); var _SourceMapSource = _interopRequireDefault(require("webpack-sources/lib/SourceMapSource")); var _sourceMap = require("source-map"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } const filterDefault = file => file.endsWith('.css'); const createRegexpFilter = regex => str => regex.test(str); const isFilterType = inst => typeof inst === 'function' || inst instanceof RegExp; const getOutputAssetFilename = postfix => file => { const parsed = _path.default.parse(file); parsed.ext = `.${postfix}${parsed.ext}`; parsed.base = `${parsed.name}${parsed.ext}`; return _path.default.format(parsed); }; const pluginName = 'csso-webpack-plugin'; const unCamelCase = str => str.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`); /* New webpack 4 API, for webpack 2-3 compatibility used .plugin('...', cb) */ const pluginCompatibility = (caller, hook, tapAction, cb) => { if (caller.hooks) { caller.hooks[hook][tapAction](pluginName, cb); return; } caller.plugin(unCamelCase(hook), cb); }; const tapOptimizeChunkAssets = (compiler, compilation, cb) => { /* New webpack 5 API, for webpack 4 are using optimizeChunkAssets */ if (compilation.hooks && compilation.hooks.processAssets) { compilation.hooks.processAssets.tapPromise({ name: pluginName, stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE, additionalAssets: true }, assets => cb(Object.keys(assets))); return; } pluginCompatibility(compilation, 'optimizeChunkAssets', 'tapAsync', (chunks, done) => { Promise.all(chunks.map(chunk => cb(chunk.files))) /* it's important not to pass any args inside `done` NOT: .then(done), ONLY: .then(() => done()) */ .then(() => done()); }); }; const getAsset = (compilation, name) => { if (compilation.getAsset) { const { source } = compilation.getAsset(name); return source; } return compilation.assets[name]; }; class CssoWebpackPlugin { constructor(opts, filter) { this.options = opts; this.filter = filter; this.pluginOutputPostfix = null; if (isFilterType(opts) && filter === undefined) { this.filter = opts; this.options = undefined; } if (this.filter === undefined) { this.filter = filterDefault; } if (this.filter instanceof RegExp) { this.filter = createRegexpFilter(this.filter); } if (typeof this.filter !== 'function') { throw new Error('filter should be one of these types: function, regexp, undefined'); } const _ref = this.options || {}, { pluginOutputPostfix } = _ref, options = _objectWithoutPropertiesLoose(_ref, ["pluginOutputPostfix"]); if (pluginOutputPostfix) { this.pluginOutputPostfix = typeof pluginOutputPostfix === 'function' ? pluginOutputPostfix : getOutputAssetFilename(pluginOutputPostfix); } this.options = options; } apply(compiler) { pluginCompatibility(compiler, 'compilation', 'tap', compilation => { const options = this.options; const { pluginOutputPostfix } = this; const compress = assets => Promise.all(assets.map(async name => { try { if (!this.filter(name)) { return; } let source; let sourceMap; const asset = getAsset(compilation, name); if (asset.sourceAndMap) { const sourceAndMap = asset.sourceAndMap(); sourceMap = sourceAndMap.map; source = sourceAndMap.source; } else { sourceMap = asset.map(); source = asset.source(); } if (Buffer.isBuffer(source)) { source = source.toString('utf-8'); } if (options.sourceMap !== undefined) { compilation.warnings.push(new Error('CssoWebpackPlugin: ' + '“sourceMap” option is DEPRECATED. ' + 'Use webpack “devtool” instead.\n\tFor more info about the usage see ' + 'https://github.com/zoobestik/csso-webpack-plugin/releases/tag/v1.0.0-beta.8')); } let fileOutput = name; if (pluginOutputPostfix) { fileOutput = pluginOutputPostfix(name); } let { css, map } = _csso.default.minify(source, Object.assign({}, options, { filename: fileOutput, sourceMap: Boolean(compiler.options.devtool) })); if (map && sourceMap) { const consumerMap = await new _sourceMap.SourceMapConsumer(sourceMap); map.applySourceMap(consumerMap, fileOutput); } if (!map) { map = sourceMap; } compilation.assets[fileOutput] = map ? new _SourceMapSource.default(css, fileOutput, map.toJSON ? map.toJSON() : map) : new _RawSource.default(css); } catch (err) { const prefix = `${name} from CssoWebpackPlugin\n`; const { message, parseError, stack } = err; let error = `${message} ${stack}`; if (parseError) { error = `${message} [${name}:${parseError.line}:${parseError.column}]`; } compilation.errors.push(new Error(`${prefix}${error}`)); } })); tapOptimizeChunkAssets(compiler, compilation, compress); }); } } exports.default = CssoWebpackPlugin;