diff --git a/README.md b/README.md index 7a01bc5..f6fb3bb 100644 --- a/README.md +++ b/README.md @@ -381,7 +381,10 @@ module.exports = { Type: ```ts -type deleteOriginalAssets = boolean | "keep-source-map"; +type deleteOriginalAssets = + | boolean + | "keep-source-map" + | ((name: string) => boolean); ``` Default: `false` @@ -400,7 +403,7 @@ module.exports = { }; ``` -To exclude sourcemaps from compression +To exclude sourcemaps from compression: ```js module.exports = { @@ -413,6 +416,25 @@ module.exports = { }; ``` +Using a custom function: + +```js +module.exports = { + plugins: [ + new CompressionPlugin({ + exclude: /.map$/, + deleteOriginalAssets: (name) => { + if (/\.js$/.test(name)) { + return false; + } + + return true; + }, + }), + ], +}; +``` + ## Examples ### Using Zopfli diff --git a/src/index.js b/src/index.js index 4e2c0ae..848d359 100644 --- a/src/index.js +++ b/src/index.js @@ -58,7 +58,7 @@ const schema = require("./options.json"); */ /** - * @typedef {boolean | "keep-source-map"} DeleteOriginalAssets + * @typedef {boolean | "keep-source-map" | ((name: string) => boolean)} DeleteOriginalAssets */ /** @@ -378,9 +378,17 @@ class CompressionPlugin { // @ts-ignore related: { sourceMap: null }, }); - } - compilation.deleteAsset(name); + compilation.deleteAsset(name); + } else if ( + typeof this.options.deleteOriginalAssets === "function" + ) { + if (this.options.deleteOriginalAssets(name)) { + compilation.deleteAsset(name); + } + } else { + compilation.deleteAsset(name); + } } else { compilation.updateAsset(name, source, { related: { [relatedName]: newFilename }, diff --git a/src/options.json b/src/options.json index ba0c91e..25fe9ca 100644 --- a/src/options.json +++ b/src/options.json @@ -98,6 +98,9 @@ { "type": "boolean" }, + { + "instanceof": "Function" + }, { "enum": ["keep-source-map"] } diff --git a/test/CompressionPlugin.test.js b/test/CompressionPlugin.test.js index b12556e..f704a40 100644 --- a/test/CompressionPlugin.test.js +++ b/test/CompressionPlugin.test.js @@ -25,8 +25,8 @@ describe("CompressionPlugin", () => { { output: { path: `${__dirname}/dist`, - filename: "[name].js?var=[hash]", - chunkFilename: "[id].[name].js?ver=[hash]", + filename: "[name].js?var=[contenthash]", + chunkFilename: "[id].[name].js?ver=[contenthash]", }, }, ); @@ -48,8 +48,8 @@ describe("CompressionPlugin", () => { devtool: "source-map", output: { path: `${__dirname}/dist`, - filename: "[name].js?var=[hash]", - chunkFilename: "[id].[name].js?ver=[hash]", + filename: "[name].js?var=[contenthash]", + chunkFilename: "[id].[name].js?ver=[contenthash]", }, }, ); @@ -72,8 +72,8 @@ describe("CompressionPlugin", () => { { output: { path: `${__dirname}/dist`, - filename: "[name].js?var=[hash]", - chunkFilename: "[id].[name].js?ver=[hash]", + filename: "[name].js?var=[contenthash]", + chunkFilename: "[id].[name].js?ver=[contenthash]", }, module: { rules: [ @@ -119,8 +119,8 @@ describe("CompressionPlugin", () => { { output: { path: `${__dirname}/dist`, - filename: "[name].js?var=[hash]", - chunkFilename: "[id].[name].js?ver=[hash]", + filename: "[name].js?var=[contenthash]", + chunkFilename: "[id].[name].js?ver=[contenthash]", }, }, ); @@ -484,8 +484,8 @@ describe("CompressionPlugin", () => { { output: { path: `${__dirname}/dist`, - filename: "[name].js?var=[hash]", - chunkFilename: "[id].[name].js?ver=[hash]", + filename: "[name].js?var=[contenthash]", + chunkFilename: "[id].[name].js?ver=[contenthash]", }, }, ); @@ -508,8 +508,8 @@ describe("CompressionPlugin", () => { { output: { path: `${__dirname}/dist`, - filename: "[name].js?var=[hash]", - chunkFilename: "[id].[name].js?ver=[hash]", + filename: "[name].js?var=[contenthash]", + chunkFilename: "[id].[name].js?ver=[contenthash]", }, }, ); diff --git a/test/__snapshots__/CompressionPlugin.test.js.snap b/test/__snapshots__/CompressionPlugin.test.js.snap index 3b573e3..6a3dffb 100644 --- a/test/__snapshots__/CompressionPlugin.test.js.snap +++ b/test/__snapshots__/CompressionPlugin.test.js.snap @@ -1319,10 +1319,10 @@ exports[`CompressionPlugin should work child compilations: assets 1`] = ` }, ], [ - "async.async.js?ver=59fa7d38343840d3f6ca", + "async.async.js?ver=cd3aed5809a2faa4eb5a", 194, { - "fullhash": "59fa7d38343840d3f6ca", + "contenthash": "cd3aed5809a2faa4eb5a", "immutable": true, "javascriptModule": false, "related": { @@ -1352,24 +1352,24 @@ exports[`CompressionPlugin should work child compilations: assets 1`] = ` ], [ "main.js.gz", - 4042, + 4018, { "compressed": true, "immutable": true, - "size": 4042, + "size": 4018, }, ], [ - "main.js?var=59fa7d38343840d3f6ca", - 16258, + "main.js?var=87e4bf99b728fffc08a0", + 16101, { - "fullhash": "59fa7d38343840d3f6ca", + "contenthash": "87e4bf99b728fffc08a0", "immutable": true, "javascriptModule": false, "related": { "gzipped": "main.js.gz", }, - "size": 16258, + "size": 16101, }, ], ] @@ -1511,10 +1511,10 @@ exports[`CompressionPlugin should work with assets info: assets 1`] = ` }, ], [ - "async.async.js?ver=e30bb673a67a1e8f00d2", + "async.async.js?ver=ff0ad4032ae148f14da4", 194, { - "fullhash": "e30bb673a67a1e8f00d2", + "contenthash": "ff0ad4032ae148f14da4", "immutable": true, "javascriptModule": false, "related": { @@ -1544,44 +1544,44 @@ exports[`CompressionPlugin should work with assets info: assets 1`] = ` ], [ "main.js.gz", - 4078, + 4070, { "compressed": true, "immutable": true, - "size": 4078, + "size": 4070, }, ], [ "main.js.map.gz", - 4164, + 4158, { "compressed": true, - "size": 4164, + "size": 4158, }, ], [ - "main.js.map?var=e30bb673a67a1e8f00d2", - 13212, + "main.js.map?var=73bfdc1831ffc69a2d3f", + 13104, { "development": true, "related": { "gzipped": "main.js.map.gz", }, - "size": 13212, + "size": 13104, }, ], [ - "main.js?var=e30bb673a67a1e8f00d2", - 16319, + "main.js?var=73bfdc1831ffc69a2d3f", + 16162, { - "fullhash": "e30bb673a67a1e8f00d2", + "contenthash": "73bfdc1831ffc69a2d3f", "immutable": true, "javascriptModule": false, "related": { "gzipped": "main.js.gz", - "sourceMap": "main.js.map?var=e30bb673a67a1e8f00d2", + "sourceMap": "main.js.map?var=73bfdc1831ffc69a2d3f", }, - "size": 16319, + "size": 16162, }, ], ] @@ -1712,10 +1712,10 @@ exports[`CompressionPlugin should work with multiple plugins: assets 1`] = ` }, ], [ - "async.async.js?ver=5bff95cff1ab52803d05", + "async.async.js?ver=cd3aed5809a2faa4eb5a", 194, { - "fullhash": "5bff95cff1ab52803d05", + "contenthash": "cd3aed5809a2faa4eb5a", "immutable": true, "javascriptModule": false, "related": { @@ -1729,45 +1729,45 @@ exports[`CompressionPlugin should work with multiple plugins: assets 1`] = ` ], [ "main.js.br", - 3538, + 3514, { "compressed": true, "immutable": true, - "size": 3538, + "size": 3514, }, ], [ "main.js.compress", - 16261, + 16104, { "compressed": true, "immutable": true, - "size": 16261, + "size": 16104, }, ], [ "main.js.custom?foo=bar#hash", - 16261, + 16104, { "compressed": true, "immutable": true, - "size": 16261, + "size": 16104, }, ], [ "main.js.gz", - 4045, + 4021, { "compressed": true, "immutable": true, - "size": 4045, + "size": 4021, }, ], [ - "main.js?var=5bff95cff1ab52803d05", - 16261, + "main.js?var=6d8b5bc920f6f6bff225", + 16104, { - "fullhash": "5bff95cff1ab52803d05", + "contenthash": "6d8b5bc920f6f6bff225", "immutable": true, "javascriptModule": false, "related": { @@ -1776,7 +1776,7 @@ exports[`CompressionPlugin should work with multiple plugins: assets 1`] = ` "customed": "main.js.custom?foo=bar#hash", "gzipped": "main.js.gz", }, - "size": 16261, + "size": 16104, }, ], ] @@ -1828,10 +1828,10 @@ exports[`CompressionPlugin should work: assets 1`] = ` }, ], [ - "async.async.js?ver=5bff95cff1ab52803d05", + "async.async.js?ver=cd3aed5809a2faa4eb5a", 194, { - "fullhash": "5bff95cff1ab52803d05", + "contenthash": "cd3aed5809a2faa4eb5a", "immutable": true, "javascriptModule": false, "related": { @@ -1842,24 +1842,24 @@ exports[`CompressionPlugin should work: assets 1`] = ` ], [ "main.js.gz", - 4045, + 4021, { "compressed": true, "immutable": true, - "size": 4045, + "size": 4021, }, ], [ - "main.js?var=5bff95cff1ab52803d05", - 16261, + "main.js?var=6d8b5bc920f6f6bff225", + 16104, { - "fullhash": "5bff95cff1ab52803d05", + "contenthash": "6d8b5bc920f6f6bff225", "immutable": true, "javascriptModule": false, "related": { "gzipped": "main.js.gz", }, - "size": 16261, + "size": 16104, }, ], ] diff --git a/test/__snapshots__/deleteOriginalAssets.test.js.snap b/test/__snapshots__/deleteOriginalAssets.test.js.snap index 62db185..a20c894 100644 --- a/test/__snapshots__/deleteOriginalAssets.test.js.snap +++ b/test/__snapshots__/deleteOriginalAssets.test.js.snap @@ -53,6 +53,69 @@ exports[`"deleteOriginalAssets" option should delete original assets and keep so exports[`"deleteOriginalAssets" option should delete original assets and keep source maps with option "keep-source-map": warnings 1`] = `[]`; +exports[`"deleteOriginalAssets" option should work and delete original assets when function used : assets 1`] = ` +[ + [ + "09a1a1112c577c2794359715edfcb5ac.png", + 78117, + { + "immutable": true, + "size": 78117, + "sourceFilename": "icon.png", + }, + ], + [ + "09a1a1112c577c2794359715edfcb5ac.png.gz", + 73507, + { + "compressed": true, + "immutable": true, + "size": 73507, + }, + ], + [ + "23fc1d3ac606d117e05a140e0de79806.svg", + 672, + { + "immutable": true, + "size": 672, + "sourceFilename": "icon.svg", + }, + ], + [ + "23fc1d3ac606d117e05a140e0de79806.svg.gz", + 390, + { + "compressed": true, + "immutable": true, + "size": 390, + }, + ], + [ + "async.async.55e6e9a872bcc7d4b226.js.gz", + 136, + { + "compressed": true, + "immutable": true, + "size": 136, + }, + ], + [ + "main.3d33e8cae1a5b505b55e.js.gz", + 4019, + { + "compressed": true, + "immutable": true, + "size": 4019, + }, + ], +] +`; + +exports[`"deleteOriginalAssets" option should work and delete original assets when function used : errors 1`] = `[]`; + +exports[`"deleteOriginalAssets" option should work and delete original assets when function used : warnings 1`] = `[]`; + exports[`"deleteOriginalAssets" option should work and delete original assets: assets 1`] = ` [ [ diff --git a/test/__snapshots__/validate-options.test.js.snap b/test/__snapshots__/validate-options.test.js.snap index 30546c3..0a39f8b 100644 --- a/test/__snapshots__/validate-options.test.js.snap +++ b/test/__snapshots__/validate-options.test.js.snap @@ -22,22 +22,24 @@ exports[`validate options should throw an error on the "compressionOptions" opti exports[`validate options should throw an error on the "deleteOriginalAssets" option with "true" value 1`] = ` "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema. - options.deleteOriginalAssets should be one of these: - boolean | "keep-source-map" + boolean | function | "keep-source-map" -> Whether to delete the original assets or not. -> Read more at https://github.com/webpack-contrib/compression-webpack-plugin/#deleteoriginalassets Details: * options.deleteOriginalAssets should be a boolean. + * options.deleteOriginalAssets should be an instance of function. * options.deleteOriginalAssets should be "keep-source-map"." `; exports[`validate options should throw an error on the "deleteOriginalAssets" option with "unknown" value 1`] = ` "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema. - options.deleteOriginalAssets should be one of these: - boolean | "keep-source-map" + boolean | function | "keep-source-map" -> Whether to delete the original assets or not. -> Read more at https://github.com/webpack-contrib/compression-webpack-plugin/#deleteoriginalassets Details: * options.deleteOriginalAssets should be a boolean. + * options.deleteOriginalAssets should be an instance of function. * options.deleteOriginalAssets should be "keep-source-map"." `; diff --git a/test/deleteOriginalAssets.test.js b/test/deleteOriginalAssets.test.js index a382809..b8687f1 100644 --- a/test/deleteOriginalAssets.test.js +++ b/test/deleteOriginalAssets.test.js @@ -53,6 +53,25 @@ describe('"deleteOriginalAssets" option', () => { expect(getErrors(stats)).toMatchSnapshot("errors"); }); + it("should work and delete original assets when function used ", async () => { + new CompressionPlugin({ + minRatio: 1, + deleteOriginalAssets: (name) => { + if (/\.js$/.test(name)) { + return true; + } + + return false; + }, + }).apply(compiler); + + const stats = await compile(compiler); + + expect(getAssetsNameAndSize(stats, compiler)).toMatchSnapshot("assets"); + expect(getWarnings(stats)).toMatchSnapshot("warnings"); + expect(getErrors(stats)).toMatchSnapshot("errors"); + }); + it("should work and report errors on duplicate assets", async () => { compiler = getCompiler("./entry.js"); diff --git a/test/validate-options.test.js b/test/validate-options.test.js index 174cdac..3da9177 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -56,7 +56,7 @@ describe("validate options", () => { failure: ["0.8"], }, deleteOriginalAssets: { - success: [true, false, "keep-source-map"], + success: [true, false, "keep-source-map", () => true], failure: ["true", "unknown"], }, unknown: { diff --git a/types/index.d.ts b/types/index.d.ts index 09ab8c0..52f9847 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -38,7 +38,7 @@ export = CompressionPlugin; * @typedef {string | ((fileData: PathData) => string)} Filename */ /** - * @typedef {boolean | "keep-source-map"} DeleteOriginalAssets + * @typedef {boolean | "keep-source-map" | ((name: string) => boolean)} DeleteOriginalAssets */ /** * @template T @@ -180,7 +180,10 @@ type PathData = { [key: string]: any; }; type Filename = string | ((fileData: PathData) => string); -type DeleteOriginalAssets = boolean | "keep-source-map"; +type DeleteOriginalAssets = + | boolean + | "keep-source-map" + | ((name: string) => boolean); type BasePluginOptions = { test?: Rules | undefined; include?: Rules | undefined;