diff --git a/README.md b/README.md index 402084a..7a44dc1 100644 --- a/README.md +++ b/README.md @@ -222,6 +222,7 @@ minify: - **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array. - Support one-liner, `include: ['*.html','*.css','*.js']`. - Must include asterisk and single quotes. `.html` is invalid. `'*.html'` is valid. +- **ensureCompressed** - Ensure the compressed file is smaller than the original, otherwise do not output. Defaults to `true`. - **globOptions** - See [globbing](#globbing) section. - **level** - Compression level; lower value may results in faster compression but slightly larger (compressed) file. Range `1-9`. Defaults to `9`, or the value of [`zlib.constants.Z_BEST_COMPRESSION`](https://nodejs.org/docs/latest-v12.x/api/zlib.html#zlib_zlib_constants) @@ -252,6 +253,7 @@ minify: - **priority** - Plugin's priority. Defaults to `10`. - **verbose** - Verbose output. Defaults to `false`. - **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array. +- **ensureCompressed** - Ensure the compressed file is smaller than the original, otherwise do not output. Defaults to `true`. - **globOptions** - See [globbing](#globbing) section. - **level** - Compression level. Range `1-11`. Defaults to `11`, or the value of [`zlib.constants.BROTLI_MAX_QUALITY`](https://nodejs.org/docs/latest-v12.x/api/zlib.html#zlib_brotli_constants) @@ -282,6 +284,7 @@ minify: - **priority** - Plugin's priority. Defaults to `10`. - **verbose** - Verbose output. Defaults to `false`. - **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array. +- **ensureCompressed** - Ensure the compressed file is smaller than the original, otherwise do not output. Defaults to `true`. - **globOptions** - See [globbing](#globbing) section. - **level** - Compression level. Range `1-22`. Defaults to `3`, or the value of [`DEFAULT_LEVEL`](https://github.com/mongodb-js/zstd/blob/a3a08c61c9045411c8275e248498dbc583457fb5/src/lib.rs#L9) diff --git a/index.js b/index.js index a646f36..85d4033 100644 --- a/index.js +++ b/index.js @@ -85,6 +85,7 @@ hexo.config.minify.gzip = { priority: 10, verbose: false, include: ['*.html', '*.css', '*.js', '*.map', '*.wasm', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json', '*.webmanifest'], + ensureCompressed: true, globOptions: { basename: true }, ...hexo.config.minify.gzip } @@ -94,6 +95,7 @@ hexo.config.minify.brotli = { priority: 10, verbose: false, include: ['*.html', '*.css', '*.js', '*.map', '*.wasm', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json', '*.webmanifest'], + ensureCompressed: true, globOptions: { basename: true }, ...hexo.config.minify.brotli } @@ -103,6 +105,7 @@ hexo.config.minify.zstd = { priority: 10, verbose: false, include: ['*.html', '*.css', '*.js', '*.map', '*.wasm', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json', '*.webmanifest'], + ensureCompressed: true, globOptions: { basename: true }, ...hexo.config.minify.zstd } diff --git a/lib/tools.js b/lib/tools.js index 2268fd1..d381d4c 100644 --- a/lib/tools.js +++ b/lib/tools.js @@ -54,10 +54,10 @@ function match(paths = [], patterns = [], options = {}) { } /** - * @param {string} original - * @param {string} ext - * @param {string} minified + * @param {{ length: number }} original + * @param {{ length: number }} minified * @param {string} path + * @param {string} ext */ function logFn(original, minified, path, ext) { const saved = ((original.length - minified.length) / original.length * 100).toFixed(2) diff --git a/lib/zlib.js b/lib/zlib.js index 5b3a8f5..e3de80b 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -12,7 +12,7 @@ function gzipFn() { const route = hexo.route /** @type {string[]} */ const routeList = route.list() - const { globOptions, include, verbose } = options + const { globOptions, include, verbose, ensureCompressed } = options let level = options.level if (typeof level !== 'number') level = zlib.constants.Z_BEST_COMPRESSION @@ -25,9 +25,11 @@ function gzipFn() { if (assetTxt.length) { try { const result = await gzip(assetTxt, { level }) - if (verbose) logFn.call(this, assetTxt, result, path, 'gzip') - resolve(route.set(path + '.gz', result)) - return + const buffer = Buffer.from(assetTxt) + if (verbose) logFn.call(this, buffer, result, path, 'gzip') + if (!ensureCompressed || buffer.length > result.length) { + route.set(path + '.gz', result) + } } catch (err) { reject(new Error(`Path: ${path}\n${err}`)) } @@ -45,7 +47,7 @@ function brotliFn() { const route = hexo.route /** @type {string[]} */ const routeList = route.list() - const { globOptions, include, verbose } = options + const { globOptions, include, verbose, ensureCompressed } = options let level = options.level if (typeof level !== 'number') level = zlib.constants.BROTLI_MAX_QUALITY @@ -58,8 +60,11 @@ function brotliFn() { if (assetTxt.length) { try { const result = await br(assetTxt, { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: level } }) - if (verbose) logFn.call(this, assetTxt, result, path, 'brotli') - route.set(path + '.br', result) + const buffer = Buffer.from(assetTxt) + if (verbose) logFn.call(this, buffer, result, path, 'brotli') + if (!ensureCompressed || buffer.length > result.length) { + route.set(path + '.br', result) + } } catch (err) { reject(new Error(`Path: ${path}\n${err}`)) } diff --git a/lib/zstd.js b/lib/zstd.js index 3b95bfd..a3b6a75 100644 --- a/lib/zstd.js +++ b/lib/zstd.js @@ -9,7 +9,7 @@ function zstdFn() { const route = hexo.route /** @type {string[]} */ const routeList = route.list() - const { globOptions, include, verbose } = options + const { globOptions, include, verbose, ensureCompressed } = options let level = options.level if (typeof level !== 'number') level = undefined @@ -23,8 +23,10 @@ function zstdFn() { try { const input = Buffer.from(assetTxt, 'utf-8') const result = await zstd(input, level) - if (verbose) logFn.call(this, assetTxt, result, path, 'zstd') - route.set(path + '.zst', result) + if (verbose) logFn.call(this, input, result, path, 'zstd') + if (!ensureCompressed || input.length > result.length) { + route.set(path + '.zst', result) + } } catch (err) { reject(new Error(`Path: ${path}\n${err}`)) }