| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { |
| value: true |
| }); |
| exports.default = void 0; |
| |
| var _crypto = _interopRequireDefault(require("crypto")); |
| |
| var _path = _interopRequireDefault(require("path")); |
| |
| var _webpack = _interopRequireWildcard(require("webpack")); |
| |
| var _schemaUtils = require("schema-utils"); |
| |
| var _serializeJavascript = _interopRequireDefault(require("serialize-javascript")); |
| |
| var _options = _interopRequireDefault(require("./options.json")); |
| |
| function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } |
| |
| function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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; } |
| |
| function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
| |
| /* |
| MIT License http://www.opensource.org/licenses/mit-license.php |
| Author Tobias Koppers @sokra |
| */ |
| const { |
| RawSource |
| } = // eslint-disable-next-line global-require |
| _webpack.default.sources || require("webpack-sources"); |
| |
| class CompressionPlugin { |
| constructor(options = {}) { |
| (0, _schemaUtils.validate)(_options.default, options, { |
| name: "Compression Plugin", |
| baseDataPath: "options" |
| }); |
| const { |
| test, |
| include, |
| exclude, |
| cache = true, |
| algorithm = "gzip", |
| compressionOptions = {}, |
| filename = "[path][base].gz", |
| threshold = 0, |
| minRatio = 0.8, |
| deleteOriginalAssets = false |
| } = options; |
| this.options = { |
| test, |
| include, |
| exclude, |
| cache, |
| algorithm, |
| compressionOptions, |
| filename, |
| threshold, |
| minRatio, |
| deleteOriginalAssets |
| }; |
| this.algorithm = this.options.algorithm; |
| |
| if (typeof this.algorithm === "string") { |
| // eslint-disable-next-line global-require |
| const zlib = require("zlib"); |
| |
| this.algorithm = zlib[this.algorithm]; |
| |
| if (!this.algorithm) { |
| throw new Error(`Algorithm "${this.options.algorithm}" is not found in "zlib"`); |
| } |
| |
| const defaultCompressionOptions = { |
| gzip: { |
| level: zlib.constants.Z_BEST_COMPRESSION |
| }, |
| deflate: { |
| level: zlib.constants.Z_BEST_COMPRESSION |
| }, |
| deflateRaw: { |
| level: zlib.constants.Z_BEST_COMPRESSION |
| }, |
| brotliCompress: { |
| params: { |
| [zlib.constants.BROTLI_PARAM_QUALITY]: zlib.constants.BROTLI_MAX_QUALITY |
| } |
| } |
| }[algorithm] || {}; |
| this.options.compressionOptions = { ...defaultCompressionOptions, |
| ...this.options.compressionOptions |
| }; |
| } |
| } // eslint-disable-next-line consistent-return |
| |
| |
| static getAsset(compilation, name) { |
| // New API |
| if (compilation.getAsset) { |
| return compilation.getAsset(name); |
| } |
| |
| if (compilation.assets[name]) { |
| return { |
| name, |
| source: compilation.assets[name], |
| info: {} |
| }; |
| } |
| } |
| |
| static emitAsset(compilation, name, source, assetInfo) { |
| // New API |
| if (compilation.emitAsset) { |
| compilation.emitAsset(name, source, assetInfo); |
| } // eslint-disable-next-line no-param-reassign |
| |
| |
| compilation.assets[name] = source; |
| } |
| |
| static updateAsset(compilation, name, newSource, assetInfo) { |
| // New API |
| if (compilation.updateAsset) { |
| compilation.updateAsset(name, newSource, assetInfo); |
| } // eslint-disable-next-line no-param-reassign |
| |
| |
| compilation.assets[name] = newSource; |
| } |
| |
| static deleteAsset(compilation, name) { |
| // New API |
| if (compilation.deleteAsset) { |
| compilation.deleteAsset(name); |
| } // eslint-disable-next-line no-param-reassign |
| |
| |
| delete compilation.assets[name]; |
| } |
| |
| runCompressionAlgorithm(input) { |
| return new Promise((resolve, reject) => { |
| this.algorithm(input, this.options.compressionOptions, (error, result) => { |
| if (error) { |
| return reject(error); |
| } |
| |
| if (!Buffer.isBuffer(result)) { |
| // eslint-disable-next-line no-param-reassign |
| result = Buffer.from(result); |
| } |
| |
| return resolve(result); |
| }); |
| }); |
| } |
| |
| async compress(compilation, assets, CacheEngine, weakCache) { |
| const assetNames = Object.keys(typeof assets === "undefined" ? compilation.assets : assets).filter(assetName => // eslint-disable-next-line no-undefined |
| _webpack.ModuleFilenameHelpers.matchObject.bind(undefined, this.options)(assetName)); |
| |
| if (assetNames.length === 0) { |
| return Promise.resolve(); |
| } |
| |
| const scheduledTasks = []; |
| const cache = new CacheEngine(compilation, { |
| cache: this.options.cache |
| }, weakCache); |
| |
| for (const name of assetNames) { |
| scheduledTasks.push((async () => { |
| const { |
| source: inputSource, |
| info |
| } = CompressionPlugin.getAsset(compilation, name); |
| |
| if (info.compressed) { |
| return; |
| } |
| |
| let relatedName; |
| |
| if (typeof this.options.algorithm === "function") { |
| let filenameForRelatedName = this.options.filename; |
| const index = filenameForRelatedName.lastIndexOf("?"); |
| |
| if (index >= 0) { |
| filenameForRelatedName = filenameForRelatedName.substr(0, index); |
| } |
| |
| relatedName = `${_path.default.extname(filenameForRelatedName).slice(1)}ed`; |
| } else if (this.options.algorithm === "gzip") { |
| relatedName = "gzipped"; |
| } else { |
| relatedName = `${this.options.algorithm}ed`; |
| } |
| |
| if (info.related && info.related[relatedName]) { |
| return; |
| } |
| |
| let input = inputSource.source(); |
| |
| if (!Buffer.isBuffer(input)) { |
| input = Buffer.from(input); |
| } |
| |
| if (input.length < this.options.threshold) { |
| return; |
| } |
| |
| const cacheData = { |
| inputSource |
| }; |
| |
| if (CompressionPlugin.isWebpack4()) { |
| cacheData.cacheKeys = { |
| nodeVersion: process.version, |
| // eslint-disable-next-line global-require |
| "compression-webpack-plugin": require("../package.json").version, |
| algorithm: this.algorithm, |
| originalAlgorithm: this.options.algorithm, |
| compressionOptions: this.options.compressionOptions, |
| name, |
| contentHash: _crypto.default.createHash("md4").update(input).digest("hex") |
| }; |
| } else { |
| cacheData.name = (0, _serializeJavascript.default)({ |
| name, |
| algorithm: this.options.algorithm, |
| compressionOptions: this.options.compressionOptions |
| }); |
| } |
| |
| let output = await cache.get(cacheData, { |
| RawSource |
| }); |
| |
| if (!output) { |
| try { |
| output = new RawSource(await this.runCompressionAlgorithm(input)); |
| } catch (error) { |
| compilation.errors.push(error); |
| return; |
| } |
| |
| cacheData.output = output; |
| await cache.store(cacheData); |
| } |
| |
| if (output.source().length / input.length > this.options.minRatio) { |
| return; |
| } |
| |
| const match = /^([^?#]*)(\?[^#]*)?(#.*)?$/.exec(name); |
| const [, replacerFile] = match; |
| const replacerQuery = match[2] || ""; |
| const replacerFragment = match[3] || ""; |
| |
| const replacerExt = _path.default.extname(replacerFile); |
| |
| const replacerBase = _path.default.basename(replacerFile); |
| |
| const replacerName = replacerBase.slice(0, replacerBase.length - replacerExt.length); |
| const replacerPath = replacerFile.slice(0, replacerFile.length - replacerBase.length); |
| const pathData = { |
| file: replacerFile, |
| query: replacerQuery, |
| fragment: replacerFragment, |
| path: replacerPath, |
| base: replacerBase, |
| name: replacerName, |
| ext: replacerExt || "" |
| }; |
| let newFilename = this.options.filename; |
| |
| if (typeof newFilename === "function") { |
| newFilename = newFilename(pathData); |
| } |
| |
| const newName = newFilename.replace(/\[(file|query|fragment|path|base|name|ext)]/g, (p0, p1) => pathData[p1]); |
| const newInfo = { |
| compressed: true |
| }; |
| |
| if (info.immutable && /(\[name]|\[base]|\[file])/.test(newFilename)) { |
| newInfo.immutable = true; |
| } |
| |
| if (this.options.deleteOriginalAssets) { |
| if (this.options.deleteOriginalAssets === "keep-source-map") { |
| // TODO `...` required only for webpack@4 |
| const updatedAssetInfo = { ...info, |
| related: { ...info.related, |
| sourceMap: null |
| } |
| }; |
| CompressionPlugin.updateAsset(compilation, name, inputSource, updatedAssetInfo); |
| } |
| |
| CompressionPlugin.deleteAsset(compilation, name); |
| } else { |
| // TODO `...` required only for webpack@4 |
| const newOriginalInfo = { ...info, |
| related: { |
| [relatedName]: newName, |
| ...info.related |
| } |
| }; |
| CompressionPlugin.updateAsset(compilation, name, inputSource, newOriginalInfo); |
| } |
| |
| CompressionPlugin.emitAsset(compilation, newName, output, newInfo); |
| })()); |
| } |
| |
| return Promise.all(scheduledTasks); |
| } |
| |
| static isWebpack4() { |
| return _webpack.version[0] === "4"; |
| } |
| |
| apply(compiler) { |
| const pluginName = this.constructor.name; |
| |
| if (CompressionPlugin.isWebpack4()) { |
| // eslint-disable-next-line global-require |
| const CacheEngine = require("./Webpack4Cache").default; |
| |
| const weakCache = new WeakMap(); |
| compiler.hooks.emit.tapPromise({ |
| name: pluginName |
| }, compilation => // eslint-disable-next-line no-undefined |
| this.compress(compilation, undefined, CacheEngine, weakCache)); |
| } else { |
| // eslint-disable-next-line global-require |
| const CacheEngine = require("./Webpack5Cache").default; |
| |
| compiler.hooks.thisCompilation.tap(pluginName, compilation => { |
| // eslint-disable-next-line global-require |
| const Compilation = require("webpack/lib/Compilation"); |
| |
| compilation.hooks.processAssets.tapPromise({ |
| name: pluginName, |
| stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER |
| }, assets => this.compress(compilation, assets, CacheEngine)); |
| compilation.hooks.statsPrinter.tap(pluginName, stats => { |
| stats.hooks.print.for("asset.info.compressed").tap("compression-webpack-plugin", (compressed, { |
| green, |
| formatFlag |
| }) => // eslint-disable-next-line no-undefined |
| compressed ? green(formatFlag("compressed")) : undefined); |
| }); |
| }); |
| } |
| } |
| |
| } |
| |
| var _default = CompressionPlugin; |
| exports.default = _default; |