From 1f4332529673fbf6ff782b8722333274d067cbf3 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Thu, 19 Aug 2021 20:57:20 +0300 Subject: [PATCH 1/4] feat: support multiple `minify` function --- README.md | 86 +++++++++++++++++-- src/index.js | 1 - src/minify.js | 61 +++++++++---- src/options.json | 33 ++++++- .../validate-options.test.js.snap | 22 +++-- test/__snapshots__/worker.test.js.snap | 23 ++--- test/validate-options.test.js | 16 ++++ test/worker.test.js | 6 +- 8 files changed, 198 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index c6b7c9b7..5cbee5be 100644 --- a/README.md +++ b/README.md @@ -60,9 +60,9 @@ Using supported `devtool` values enable source map generation. | :---------------------------------------: | :-----------------------------------------------------------------------------: | :-------------------------------------------------------------: | :--------------------------------------------------------------------------- | | **[`test`](#test)** | `String\|RegExp\|Array` | `/\.m?js(\?.*)?$/i` | Test to match files against. | | **[`include`](#include)** | `String\|RegExp\|Array` | `undefined` | Files to include. | -| **[`exclude`](#)** | `String\|RegExp\|Array` | `undefined` | Files to exclude. | +| **[`exclude`](#exclude)** | `String\|RegExp\|Array` | `undefined` | Files to exclude. | | **[`parallel`](#parallel)** | `Boolean\|Number` | `true` | Use multi-process parallel running to improve the build speed. | -| **[`minify`](#minify)** | `Function` | `undefined` | Allows you to override default minify function. | +| **[`minify`](#minify)** | `Function` | `TerserPlugin.terserMinify` | Allows you to override default minify function. | | **[`terserOptions`](#terseroptions)** | `Object` | [`default`](https://github.com/terser-js/terser#minify-options) | Terser [minify options](https://github.com/terser-js/terser#minify-options). | | **[`extractComments`](#extractcomments)** | `Boolean\|String\|RegExp\|Function<(node, comment) -> Boolean\|Object>\|Object` | `true` | Whether comments shall be extracted to a separate file. | @@ -184,8 +184,8 @@ module.exports = { ### `minify` -Type: `Function` -Default: `undefined` +Type: `Function|Array` +Default: `TerserPlugin.terserMinify` Allows you to override default minify function. By default plugin uses [terser](https://github.com/terser-js/terser) package. @@ -193,6 +193,8 @@ Useful for using and testing unpublished versions or forks. > ⚠️ **Always use `require` inside `minify` function when `parallel` option enabled**. +#### `Function` + **webpack.config.js** ```js @@ -225,13 +227,51 @@ module.exports = { }; ``` +#### `Array` + +If an array of functions is passed to the `minify` option, the `terserOptions` must also be an array. +The function index in the `minify` array corresponds to the options object with the same index in the `terserOptions` array. + +**webpack.config.js** + +```js +module.exports = { + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + terserOptions: [ + {}, // Options for the first function (CssMinimizerPlugin.swcMinify) + {}, // Options for the second function + ], + minify: [ + CssMinimizerPlugin.swcMinify, + async (input, inputSourceMap, minimizerOptions, extractComments) => { + // To do something + return { + code: `const foo = "bar"`, + map: `{"version": "3", ...}`, + warnings: [], + errors: [], + extractComments: [], + }; + }, + ], + }), + ], + }, +}; +``` + ### `terserOptions` -Type: `Object` +Type: `Object|Array` Default: [default](https://github.com/terser-js/terser#minify-options) Terser minify [options](https://github.com/terser-js/terser#minify-options). +#### `Object` + **webpack.config.js** ```js @@ -262,6 +302,42 @@ module.exports = { }; ``` +### `Array` + +If an array of functions is passed to the `minify` option, the `terserOptions` must also be an array. +The function index in the `minify` array corresponds to the options object with the same index in the `terserOptions` array. + +**webpack.config.js** + +```js +module.exports = { + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + terserOptions: [ + {}, // Options for the first function (CssMinimizerPlugin.swcMinify) + {}, // Options for the second function + ], + minify: [ + CssMinimizerPlugin.swcMinify, + async (input, inputSourceMap, minimizerOptions, extractComments) => { + // To do something + return { + code: `const foo = "bar"`, + map: `{"version": "3", ...}`, + warnings: [], + errors: [], + extractComments: [], + }; + }, + ], + }), + ], + }, +}; +``` + ### `extractComments` Type: `Boolean|String|RegExp|Function<(node, comment) -> Boolean|Object>|Object` diff --git a/src/index.js b/src/index.js index 5d6559fe..169f1244 100644 --- a/src/index.js +++ b/src/index.js @@ -101,7 +101,6 @@ import { minify as minifyFn } from "./minify"; * @property {Array} [errors] * @property {Array} [warnings] * @property {Array} [extractedComments] - * @property {Array} [extractedComments] */ /** diff --git a/src/minify.js b/src/minify.js index e2838527..7ff5b0c1 100644 --- a/src/minify.js +++ b/src/minify.js @@ -6,21 +6,52 @@ * @returns {Promise} */ async function minify(options) { - const { - name, - input, - inputSourceMap, - minify: minifyFn, - minifyOptions, - extractComments, - } = options; - - return minifyFn( - { [name]: input }, - inputSourceMap, - minifyOptions, - extractComments - ); + const minifyFns = + typeof options.minify === "function" ? [options.minify] : options.minify; + + /** + * @type {MinifyResult} + */ + const result = { code: options.input, map: options.inputSourceMap }; + + for (let i = 0; i <= minifyFns.length - 1; i++) { + const minifyFn = minifyFns[i]; + const minifyOptions = Array.isArray(options.minifyOptions) + ? options.minifyOptions[i] + : options.minifyOptions; + // eslint-disable-next-line no-await-in-loop + const minifyResult = await minifyFn( + { [options.name]: result.code }, + result.map, + minifyOptions, + options.extractComments + ); + + result.code = minifyResult.code; + + if (minifyResult.map) { + result.map = minifyResult.map; + } + + if (minifyResult.warnings && minifyResult.warnings.length > 0) { + result.warnings = (result.warnings || []).concat(minifyResult.warnings); + } + + if (minifyResult.errors && minifyResult.errors.length > 0) { + result.errors = (result.errors || []).concat(minifyResult.errors); + } + + if ( + minifyResult.extractedComments && + minifyResult.extractedComments.length > 0 + ) { + result.extractedComments = (result.extractedComments || []).concat( + minifyResult.extractedComments + ); + } + } + + return result; } /** diff --git a/src/options.json b/src/options.json index 82c7b964..4cd0a219 100644 --- a/src/options.json +++ b/src/options.json @@ -31,6 +31,10 @@ "$ref": "#/definitions/Rule" } ] + }, + "MinimizerOptions": { + "additionalProperties": true, + "type": "object" } }, "title": "TerserPluginOptions", @@ -65,10 +69,20 @@ ] }, "terserOptions": { - "description": "Options for `terser`.", + "description": "Options for `terser` (by default) or custom `minify` function.", "link": "https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions", - "additionalProperties": true, - "type": "object" + "anyOf": [ + { + "$ref": "#/definitions/MinimizerOptions" + }, + { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/MinimizerOptions" + } + } + ] }, "extractComments": { "description": "Whether comments shall be extracted to a separate file.", @@ -158,7 +172,18 @@ "minify": { "description": "Allows you to override default minify function.", "link": "https://github.com/webpack-contrib/terser-webpack-plugin#number", - "instanceof": "Function" + "anyOf": [ + { + "instanceof": "Function" + }, + { + "type": "array", + "minItems": 1, + "items": { + "instanceof": "Function" + } + } + ] } } } diff --git a/test/__snapshots__/validate-options.test.js.snap b/test/__snapshots__/validate-options.test.js.snap index cc01f413..b1a13daa 100644 --- a/test/__snapshots__/validate-options.test.js.snap +++ b/test/__snapshots__/validate-options.test.js.snap @@ -120,17 +120,27 @@ exports[`validation 8`] = ` exports[`validation 9`] = ` "Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema. - - options.minify should be an instance of function. + - options.minify should be one of these: + function | [function, ...] (should not have fewer than 1 item) -> Allows you to override default minify function. - -> Read more at https://github.com/webpack-contrib/terser-webpack-plugin#number" + -> Read more at https://github.com/webpack-contrib/terser-webpack-plugin#number + Details: + * options.minify should be an instance of function. + * options.minify should be an array: + [function, ...] (should not have fewer than 1 item)" `; exports[`validation 10`] = ` "Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema. - - options.terserOptions should be an object: - object { … } - -> Options for \`terser\`. - -> Read more at https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions" + - options.terserOptions should be one of these: + object { … } | [object { … }, ...] (should not have fewer than 1 item) + -> Options for \`terser\` (by default) or custom \`minify\` function. + -> Read more at https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions + Details: + * options.terserOptions should be an object: + object { … } + * options.terserOptions should be an array: + [object { … }, ...] (should not have fewer than 1 item)" `; exports[`validation 11`] = ` diff --git a/test/__snapshots__/worker.test.js.snap b/test/__snapshots__/worker.test.js.snap index 43d4aec6..a7a5bfb0 100644 --- a/test/__snapshots__/worker.test.js.snap +++ b/test/__snapshots__/worker.test.js.snap @@ -6,7 +6,6 @@ Object { // Comment /* duplicate */ /* duplicate */", - "extractedComments": Array [], "map": undefined, } `; @@ -14,7 +13,6 @@ Object { exports[`worker should match snapshot when minimizerOptions.compress.comments is boolean 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -22,7 +20,6 @@ Object { exports[`worker should match snapshot when minimizerOptions.compress.comments is object 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -30,7 +27,6 @@ Object { exports[`worker should match snapshot when minimizerOptions.extractComments is number 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -38,7 +34,6 @@ Object { exports[`worker should match snapshot when minimizerOptions.mangle is "null" 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -46,7 +41,6 @@ Object { exports[`worker should match snapshot when minimizerOptions.mangle is boolean 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -54,7 +48,6 @@ Object { exports[`worker should match snapshot when minimizerOptions.mangle is object 1`] = ` Object { "code": "var a=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -62,7 +55,6 @@ Object { exports[`worker should match snapshot when minimizerOptions.output.comments is string: some 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -82,7 +74,6 @@ Object { exports[`worker should match snapshot when options.extractComments is "false" 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -90,7 +81,6 @@ Object { exports[`worker should match snapshot when options.extractComments is "some" value 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -98,16 +88,18 @@ Object { exports[`worker should match snapshot when options.extractComments is "true" 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; exports[`worker should match snapshot when options.extractComments is "true" 2`] = ` -"var foo = 1;/* hello */ +Object { + "code": "var foo = 1;/* hello */ // Comment /* duplicate */ -/* duplicate */" +/* duplicate */", + "map": undefined, +} `; exports[`worker should match snapshot when options.extractComments is Function 1`] = ` @@ -137,7 +129,6 @@ Object { exports[`worker should match snapshot when options.extractComments is Object with "some" value 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -145,7 +136,6 @@ Object { exports[`worker should match snapshot when options.extractComments is Object with "true" value 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -163,7 +153,6 @@ Object { exports[`worker should match snapshot when options.extractComments is empty Object 1`] = ` Object { "code": "var foo=1;", - "extractedComments": Array [], "map": undefined, } `; @@ -171,7 +160,6 @@ Object { exports[`worker should match snapshot with extract option set to a single file 1`] = ` Object { "code": "/******/function hello(o){console.log(o)}", - "extractedComments": Array [], "map": undefined, } `; @@ -179,7 +167,6 @@ Object { exports[`worker should match snapshot with options.inputSourceMap 1`] = ` Object { "code": "function foo(f){if(f)return bar()}", - "extractedComments": Array [], "map": Object { "mappings": "AAAA,SAASA,IAAIC,GAAK,GAAIA,EAAK,OAAOC", "names": Array [ diff --git a/test/validate-options.test.js b/test/validate-options.test.js index 7ebd8d93..4c580502 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -122,6 +122,14 @@ it("validation", () => { new TerserPlugin({ minify() {} }); }).not.toThrow(); + expect(() => { + new TerserPlugin({ minify: [() => {}] }); + }).not.toThrow(); + + expect(() => { + new TerserPlugin({ minify: [() => {}, () => {}] }); + }).not.toThrow(); + expect(() => { new TerserPlugin({ minify: true }); }).toThrowErrorMatchingSnapshot(); @@ -130,6 +138,14 @@ it("validation", () => { new TerserPlugin({ terserOptions: {} }); }).not.toThrow(); + expect(() => { + new TerserPlugin({ terserOptions: [{}] }); + }).not.toThrow(); + + expect(() => { + new TerserPlugin({ terserOptions: [{}, {}] }); + }).not.toThrow(); + expect(() => { new TerserPlugin({ terserOptions: null }); }).toThrowErrorMatchingSnapshot(); diff --git a/test/worker.test.js b/test/worker.test.js index 035b3d44..21fcfc81 100644 --- a/test/worker.test.js +++ b/test/worker.test.js @@ -268,7 +268,11 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: (item) => item["test1.js"], + minify: (item) => { + return { + code: item["test1.js"], + }; + }, }; const workerResult = await transform(serialize(options)); From 55e8137267727311dae6f3102b72f13dba463302 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Thu, 19 Aug 2021 21:09:52 +0300 Subject: [PATCH 2/4] fix: types --- src/index.js | 21 ++++++++++------ src/minify.js | 10 +++++--- test/worker.test.js | 60 ++++++++++++++++++++++----------------------- 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/index.js b/src/index.js index 169f1244..5e04cdb1 100644 --- a/src/index.js +++ b/src/index.js @@ -84,14 +84,18 @@ import { minify as minifyFn } from "./minify"; * @typedef {ExtractCommentsCondition | ExtractCommentsObject} ExtractCommentsOptions */ +/** + * @typedef {TerserMinifyOptions | UglifyJSMinifyOptions | SwcMinifyOptions | EsbuildMinifyOptions | CustomMinifyOptions} minimizerOptions + */ + /** * @typedef {Object} InternalMinifyOptions * @property {string} name * @property {string} input * @property {RawSourceMap | undefined} inputSourceMap * @property {ExtractCommentsOptions | undefined} extractComments - * @property {MinifyFunction} minify - * @property {TerserMinifyOptions | CustomMinifyOptions} minifyOptions + * @property {MinifyFunction | Array} minimizer + * @property {minimizerOptions | Array} minimizerOptions */ /** @@ -435,18 +439,19 @@ class TerserPlugin { name, input, inputSourceMap, - minify: this.options.minify, - minifyOptions: { ...this.options.terserOptions }, + // TODO rename to `minimizer` in the next major release + minimizer: this.options.minify, + minimizerOptions: { ...this.options.terserOptions }, extractComments: this.options.extractComments, }; - if (typeof options.minifyOptions.module === "undefined") { + if (typeof options.minimizerOptions.module === "undefined") { if (typeof info.javascriptModule !== "undefined") { - options.minifyOptions.module = info.javascriptModule; + options.minimizerOptions.module = info.javascriptModule; } else if (/\.mjs(\?.*)?$/i.test(name)) { - options.minifyOptions.module = true; + options.minimizerOptions.module = true; } else if (/\.cjs(\?.*)?$/i.test(name)) { - options.minifyOptions.module = false; + options.minimizerOptions.module = false; } } diff --git a/src/minify.js b/src/minify.js index 7ff5b0c1..708e0af6 100644 --- a/src/minify.js +++ b/src/minify.js @@ -7,7 +7,9 @@ */ async function minify(options) { const minifyFns = - typeof options.minify === "function" ? [options.minify] : options.minify; + typeof options.minimizer === "function" + ? [options.minimizer] + : options.minimizer; /** * @type {MinifyResult} @@ -16,9 +18,9 @@ async function minify(options) { for (let i = 0; i <= minifyFns.length - 1; i++) { const minifyFn = minifyFns[i]; - const minifyOptions = Array.isArray(options.minifyOptions) - ? options.minifyOptions[i] - : options.minifyOptions; + const minifyOptions = Array.isArray(options.minimizerOptions) + ? options.minimizerOptions[i] + : options.minimizerOptions; // eslint-disable-next-line no-await-in-loop const minifyResult = await minifyFn( { [options.name]: result.code }, diff --git a/test/worker.test.js b/test/worker.test.js index 21fcfc81..69637069 100644 --- a/test/worker.test.js +++ b/test/worker.test.js @@ -9,7 +9,7 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, + minimizer: terserMinify, extractComments: false, }; const workerResult = await transform(serialize(options)); @@ -22,7 +22,7 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, + minimizer: terserMinify, extractComments: true, }; const workerResult = await transform(serialize(options)); @@ -35,7 +35,7 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, + minimizer: terserMinify, extractComments: /hello/, }; const workerResult = await transform(serialize(options)); @@ -48,7 +48,7 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, + minimizer: terserMinify, extractComments: () => true, }; const workerResult = await transform(serialize(options)); @@ -61,7 +61,7 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, + minimizer: terserMinify, extractComments: {}, }; const workerResult = await transform(serialize(options)); @@ -74,7 +74,7 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, + minimizer: terserMinify, extractComments: { condition: true, }, @@ -89,7 +89,7 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, + minimizer: terserMinify, extractComments: { condition: "some", }, @@ -104,7 +104,7 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, + minimizer: terserMinify, extractComments: { condition: "all", }, @@ -119,7 +119,7 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, + minimizer: terserMinify, extractComments: "all", }; const workerResult = await transform(serialize(options)); @@ -132,7 +132,7 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, + minimizer: terserMinify, extractComments: "some", }; const workerResult = await transform(serialize(options)); @@ -145,8 +145,8 @@ describe("worker", () => { name: "test2.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, - minifyOptions: { + minimizer: terserMinify, + minimizerOptions: { output: { comments: "all", }, @@ -162,8 +162,8 @@ describe("worker", () => { name: "test3.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, - minifyOptions: { + minimizer: terserMinify, + minimizerOptions: { compress: true, }, }; @@ -177,8 +177,8 @@ describe("worker", () => { name: "test3.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, - minifyOptions: { + minimizer: terserMinify, + minimizerOptions: { compress: { passes: 2, }, @@ -194,8 +194,8 @@ describe("worker", () => { name: "test3.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, - minifyOptions: { + minimizer: terserMinify, + minimizerOptions: { output: { comments: "some", }, @@ -211,8 +211,8 @@ describe("worker", () => { name: "test4.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, - minifyOptions: { + minimizer: terserMinify, + minimizerOptions: { output: { comments: "some", }, @@ -228,8 +228,8 @@ describe("worker", () => { const options = { name: "test5.js", input: "/******/ function hello(a) {console.log(a)}", - minify: terserMinify, - minifyOptions: { + minimizer: terserMinify, + minimizerOptions: { output: { comments: "all", }, @@ -248,7 +248,7 @@ describe("worker", () => { it("should match snapshot with options.inputSourceMap", async () => { const options = { - minify: terserMinify, + minimizer: terserMinify, name: "test6.js", input: "function foo(x) { if (x) { return bar(); not_called1(); } }", inputSourceMap: { @@ -268,7 +268,7 @@ describe("worker", () => { name: "test1.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: (item) => { + minimizer: (item) => { return { code: item["test1.js"], }; @@ -284,8 +284,8 @@ describe("worker", () => { name: "test4.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, - minifyOptions: { + minimizer: terserMinify, + minimizerOptions: { mangle: null, }, }; @@ -299,8 +299,8 @@ describe("worker", () => { name: "test4.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, - minifyOptions: { + minimizer: terserMinify, + minimizerOptions: { mangle: true, }, }; @@ -314,8 +314,8 @@ describe("worker", () => { name: "test4.js", input: "var foo = 1;/* hello */\n// Comment\n/* duplicate */\n/* duplicate */", - minify: terserMinify, - minifyOptions: { + minimizer: terserMinify, + minimizerOptions: { mangle: { toplevel: true }, }, }; From 49d549130dec307bfdb42b49f040c4f5f7ee2065 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Thu, 19 Aug 2021 21:16:37 +0300 Subject: [PATCH 3/4] fix: types --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 5e04cdb1..5804f38a 100644 --- a/src/index.js +++ b/src/index.js @@ -85,7 +85,7 @@ import { minify as minifyFn } from "./minify"; */ /** - * @typedef {TerserMinifyOptions | UglifyJSMinifyOptions | SwcMinifyOptions | EsbuildMinifyOptions | CustomMinifyOptions} minimizerOptions + * @typedef {TerserMinifyOptions | UglifyJSMinifyOptions | SwcMinifyOptions | EsbuildMinifyOptions | CustomMinifyOptions} MinimizerOptions */ /** @@ -95,7 +95,7 @@ import { minify as minifyFn } from "./minify"; * @property {RawSourceMap | undefined} inputSourceMap * @property {ExtractCommentsOptions | undefined} extractComments * @property {MinifyFunction | Array} minimizer - * @property {minimizerOptions | Array} minimizerOptions + * @property {MinimizerOptions | Array} minimizerOptions */ /** From 10b4db89e8579f71fffc03a50f59fa99c5519ad7 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 24 Aug 2021 14:15:49 +0300 Subject: [PATCH 4/4] fix: stuff --- package-lock.json | 51 +- package.json | 3 +- src/index.js | 6 +- src/minify.js | 90 +++- test/__snapshots__/minify-option.test.js.snap | 480 +----------------- test/fixtures/entry.js | 3 + test/helpers/getCompiler.js | 2 +- test/minify-option.test.js | 134 +++-- 8 files changed, 215 insertions(+), 554 deletions(-) diff --git a/package-lock.json b/package-lock.json index 498bc741..9247d1dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "license": "MIT", "dependencies": { "jest-worker": "^27.0.6", + "merge-source-map": "^1.1.0", "p-limit": "^3.1.0", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", @@ -44,7 +45,7 @@ "standard-version": "^9.3.1", "typescript": "^4.3.5", "uglify-js": "^3.14.1", - "webpack": "^5.48.0", + "webpack": "^5.51.1", "worker-loader": "^3.0.8" }, "engines": { @@ -3734,6 +3735,15 @@ "acorn-walk": "^7.1.1" } }, + "node_modules/acorn-import-assertions": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz", + "integrity": "sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -11453,6 +11463,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dependencies": { + "source-map": "^0.6.1" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -14823,15 +14841,6 @@ "node": ">=0.4.0" } }, - "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz", - "integrity": "sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -17797,6 +17806,13 @@ "acorn-walk": "^7.1.1" } }, + "acorn-import-assertions": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz", + "integrity": "sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA==", + "dev": true, + "requires": {} + }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -23634,6 +23650,14 @@ } } }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "requires": { + "source-map": "^0.6.1" + } + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -26241,13 +26265,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true - }, - "acorn-import-assertions": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz", - "integrity": "sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA==", - "dev": true, - "requires": {} } } }, diff --git a/package.json b/package.json index 81bdd7ac..cbaf8a79 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ }, "dependencies": { "jest-worker": "^27.0.6", + "merge-source-map": "^1.1.0", "p-limit": "^3.1.0", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", @@ -91,7 +92,7 @@ "standard-version": "^9.3.1", "typescript": "^4.3.5", "uglify-js": "^3.14.1", - "webpack": "^5.48.0", + "webpack": "^5.51.1", "worker-loader": "^3.0.8" }, "keywords": [ diff --git a/src/index.js b/src/index.js index 5804f38a..0f51cf25 100644 --- a/src/index.js +++ b/src/index.js @@ -441,7 +441,11 @@ class TerserPlugin { inputSourceMap, // TODO rename to `minimizer` in the next major release minimizer: this.options.minify, - minimizerOptions: { ...this.options.terserOptions }, + minimizerOptions: Array.isArray(this.options.terserOptions) + ? this.options.terserOptions.map((item) => { + return { ...item }; + }) + : { ...this.options.terserOptions }, extractComments: this.options.extractComments, }; diff --git a/src/minify.js b/src/minify.js index 708e0af6..5a0f2472 100644 --- a/src/minify.js +++ b/src/minify.js @@ -1,5 +1,6 @@ /** @typedef {import("./index.js").InternalMinifyOptions} InternalMinifyOptions */ /** @typedef {import("./index.js").MinifyResult} MinifyResult */ +/** @typedef {import("source-map").RawSourceMap} RawSourceMap */ /** * @param {InternalMinifyOptions} options @@ -14,17 +15,100 @@ async function minify(options) { /** * @type {MinifyResult} */ - const result = { code: options.input, map: options.inputSourceMap }; + const result = { code: options.input }; + + /** + * @param {RawSourceMap | undefined} oldMap + * @param {RawSourceMap | undefined} newMap + * @returns {RawSourceMap | undefined} + */ + const mergeSourceMap = (oldMap, newMap) => { + if (!oldMap) { + return newMap; + } + + if (!newMap) { + return oldMap; + } + + // eslint-disable-next-line global-require + const sourceMap = require("source-map"); + const oldMapConsumer = new sourceMap.SourceMapConsumer(oldMap); + const newMapConsumer = new sourceMap.SourceMapConsumer(newMap); + const mergedMapGenerator = new sourceMap.SourceMapGenerator(); + + newMapConsumer.eachMapping((m) => { + // pass when `originalLine` is null. + // It occurs in case that the node does not have origin in original code. + if (m.originalLine == null) { + return; + } + + const origPosInOldMap = oldMapConsumer.originalPositionFor({ + line: m.originalLine, + column: m.originalColumn, + }); + + if (origPosInOldMap.source == null) { + return; + } + + mergedMapGenerator.addMapping({ + original: { + line: origPosInOldMap.line, + column: origPosInOldMap.column, + }, + generated: { + line: m.generatedLine, + column: m.generatedColumn, + }, + source: origPosInOldMap.source, + name: origPosInOldMap.name, + }); + }); + + const consumers = [oldMapConsumer, newMapConsumer]; + + consumers.forEach((consumer) => { + // @ts-ignore + consumer.sources.forEach( + /** + * @param {string} sourceFile + */ + (sourceFile) => { + // @ts-ignore + // eslint-disable-next-line no-underscore-dangle + mergedMapGenerator._sources.add(sourceFile); + + const sourceContent = consumer.sourceContentFor(sourceFile); + + if (sourceContent != null) { + mergedMapGenerator.setSourceContent(sourceFile, sourceContent); + } + } + ); + }); + + const merged = JSON.parse(mergedMapGenerator.toString()); + + merged.sourceRoot = oldMap.sourceRoot; + merged.file = oldMap.file; + + return merged; + }; + + const { inputSourceMap } = options; for (let i = 0; i <= minifyFns.length - 1; i++) { const minifyFn = minifyFns[i]; const minifyOptions = Array.isArray(options.minimizerOptions) ? options.minimizerOptions[i] : options.minimizerOptions; + // eslint-disable-next-line no-await-in-loop const minifyResult = await minifyFn( { [options.name]: result.code }, - result.map, + result.map || inputSourceMap, minifyOptions, options.extractComments ); @@ -32,7 +116,7 @@ async function minify(options) { result.code = minifyResult.code; if (minifyResult.map) { - result.map = minifyResult.map; + result.map = mergeSourceMap(inputSourceMap, minifyResult.map); } if (minifyResult.warnings && minifyResult.warnings.length > 0) { diff --git a/test/__snapshots__/minify-option.test.js.snap b/test/__snapshots__/minify-option.test.js.snap index 754509a3..d8fe7469 100644 --- a/test/__snapshots__/minify-option.test.js.snap +++ b/test/__snapshots__/minify-option.test.js.snap @@ -1,483 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`minify option should snapshot with extracting comments: assets 1`] = ` +exports[`minify option should work with multiple custom minimize functions and source map: assets 1`] = ` Object { - "main.js": "/*! For license information please see main.js.LICENSE.txt */ -(()=>{var e={293:e=>{e.exports=function(){var baz=document.getElementById(\\"root\\").innerHTML;document.getElementById(\\"demo\\").innerHTML=\\"Paragraph changed.\\"+baz}}},r={};(function t(n){var o=r[n];if(void 0!==o)return o.exports;var a=r[n]={exports:{}};return e[n](a,a.exports,t),a.exports})(293)})();", - "main.js.LICENSE.txt": "/* Foo */ -", + "main.js": "(()=>{var e={791:r=>{r.exports=function(){throw new Error(\\"test\\")},r.exports()}},n={};!function r(t){var o=n[t];if(void 0!==o)return o.exports;o=n[t]={exports:{}};return e[t](o,o.exports,r),o.exports}(791)})();", } `; -exports[`minify option should snapshot with extracting comments: errors 1`] = `Array []`; +exports[`minify option should work with multiple custom minimize functions and source map: errors 1`] = `Array []`; -exports[`minify option should snapshot with extracting comments: warnings 1`] = `Array []`; - -exports[`minify option should throw an error when an error when the "parallel" option is "false": errors 1`] = ` -Array [ - "Error: main.js from Terser -Error: Error", -] -`; - -exports[`minify option should throw an error when an error when the "parallel" option is "false": warnings 1`] = `Array []`; - -exports[`minify option should throw an error when an error when the "parallel" option is "true": errors 1`] = ` -Array [ - "Error: main.js from Terser -Error: Error", -] -`; - -exports[`minify option should throw an error when an error when the "parallel" option is "true": warnings 1`] = `Array []`; - -exports[`minify option should throw an error when an error: errors 1`] = ` -Array [ - "Error: main.js from Terser -Error: Error", -] -`; - -exports[`minify option should throw an error when an error: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\` and ECMA modules output: assets 1`] = ` -Object { - "main.js": "var n={791:e=>{/* @preserve*/const o=null;e.exports=function(){const a=2+2;console.log(a+1+2)}}},r={};function c(e){var o=r[e];if(o!==void 0)return o.exports;var _=r[e]={exports:{}};return n[e](_,_.exports,c),_.exports}var t=c(791); -", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\` and ECMA modules output: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\` and ECMA modules output: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\` and allows to set \`esbuild\` options: assets 1`] = ` -Object { - "main.js": "(()=>{var __webpack_modules__={791:module=>{/* @preserve*/const a=null;module.exports=function(){const b=2+2;console.log(b+1+2)}}},__webpack_module_cache__={};function __webpack_require__(moduleId){var cachedModule=__webpack_module_cache__[moduleId];if(cachedModule!==void 0)return cachedModule.exports;var module=__webpack_module_cache__[moduleId]={exports:{}};return __webpack_modules__[moduleId](module,module.exports,__webpack_require__),module.exports}var __webpack_exports__=__webpack_require__(791)})(); -", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\` and allows to set \`esbuild\` options: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\` and allows to set \`esbuild\` options: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\` and generate source maps: assets 1`] = ` -Object { - "main.js": "(()=>{var a={791:e=>{/* @preserve*/const o=null;e.exports=function(){const n=2+2;console.log(n+1+2)}}},r={};function c(e){var o=r[e];if(o!==void 0)return o.exports;var _=r[e]={exports:{}};return a[e](_,_.exports,c),_.exports}var t=c(791)})(); - -//# sourceMappingURL=main.js.map", - "main.js.map": "{\\"version\\":3,\\"file\\":\\"main.js\\",\\"mappings\\":\\"AAAS,KAAO,CACN,GAAI,GAAuB,CAE/B,IACC,GAAY,CAGnB,cAEA,KAAM,GAA2C,KAEjD,EAAO,QAAU,UAAe,CAC9B,KAAM,GAAI,EAAI,EACd,QAAQ,IAAI,EAAI,EAAI,MASR,EAA2B,GAG/B,WAA6B,EAAU,CAEtC,GAAI,GAAe,EAAyB,GAC5C,GAAI,IAAiB,OACpB,MAAO,GAAa,QAGrB,GAAI,GAAS,EAAyB,GAAY,CAGjD,QAAS,IAIV,SAAoB,GAAU,EAAQ,EAAO,QAAS,GAG/C,EAAO,QAQf,GAAI,GAAsB,EAAoB\\",\\"sources\\":[\\"webpack://terser-webpack-plugin/\\"],\\"sourcesContent\\":[\\"/******/ (() => { // webpackBootstrap\\\\n/******/ \\\\tvar __webpack_modules__ = ({\\\\n\\\\n/***/ 791:\\\\n/***/ ((module) => {\\\\n\\\\n// foo\\\\n/* @preserve*/\\\\n// bar\\\\nconst a = (/* unused pure expression or super */ null && (2 + 2));\\\\n\\\\nmodule.exports = function Foo() {\\\\n const b = 2 + 2;\\\\n console.log(b + 1 + 2);\\\\n};\\\\n\\\\n\\\\n/***/ })\\\\n\\\\n/******/ \\\\t});\\\\n/************************************************************************/\\\\n/******/ \\\\t// The module cache\\\\n/******/ \\\\tvar __webpack_module_cache__ = {};\\\\n/******/ \\\\t\\\\n/******/ \\\\t// The require function\\\\n/******/ \\\\tfunction __webpack_require__(moduleId) {\\\\n/******/ \\\\t\\\\t// Check if module is in cache\\\\n/******/ \\\\t\\\\tvar cachedModule = __webpack_module_cache__[moduleId];\\\\n/******/ \\\\t\\\\tif (cachedModule !== undefined) {\\\\n/******/ \\\\t\\\\t\\\\treturn cachedModule.exports;\\\\n/******/ \\\\t\\\\t}\\\\n/******/ \\\\t\\\\t// Create a new module (and put it into the cache)\\\\n/******/ \\\\t\\\\tvar module = __webpack_module_cache__[moduleId] = {\\\\n/******/ \\\\t\\\\t\\\\t// no module.id needed\\\\n/******/ \\\\t\\\\t\\\\t// no module.loaded needed\\\\n/******/ \\\\t\\\\t\\\\texports: {}\\\\n/******/ \\\\t\\\\t};\\\\n/******/ \\\\t\\\\n/******/ \\\\t\\\\t// Execute the module function\\\\n/******/ \\\\t\\\\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\\\\n/******/ \\\\t\\\\n/******/ \\\\t\\\\t// Return the exports of the module\\\\n/******/ \\\\t\\\\treturn module.exports;\\\\n/******/ \\\\t}\\\\n/******/ \\\\t\\\\n/************************************************************************/\\\\n/******/ \\\\t\\\\n/******/ \\\\t// startup\\\\n/******/ \\\\t// Load entry module and return exports\\\\n/******/ \\\\t// This entry module is referenced by other modules so it can't be inlined\\\\n/******/ \\\\tvar __webpack_exports__ = __webpack_require__(791);\\\\n/******/ \\\\t\\\\n/******/ })()\\\\n;\\"],\\"names\\":[],\\"sourceRoot\\":\\"\\"}", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\` and generate source maps: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\` and generate source maps: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\` and keep legal comments when extract comments is disabled: assets 1`] = ` -Object { - "627.627.js": "(self.webpackChunkterser_webpack_plugin=self.webpackChunkterser_webpack_plugin||[]).push([[627],{627:e=>{/*! Legal Comment *//** @license Copyright 2112 Moon. **/e.exports=Math.random()}}]); -", - "main.js": "(()=>{var b={900:(e,o,t)=>{t.e(627).then(t.t.bind(t,627,23));/*! Legal Comment *//** - * @preserve Copyright 2009 SomeThirdParty. - * Here is the full license text and copyright - * notice for this file. Note that the notice can span several - * lines and is only terminated by the closing star and slash: - *//** - * Utility functions for the foo package. - * @license Apache-2.0 - *//*! Legal Foo */e.exports=Math.random()}},g={};function r(e){var o=g[e];if(o!==void 0)return o.exports;var t=g[e]={exports:{}};return b[e](t,t.exports,r),t.exports}r.m=b,(()=>{var e=Object.getPrototypeOf?t=>Object.getPrototypeOf(t):t=>t.__proto__,o;r.t=function(t,a){if(a&1&&(t=this(t)),a&8||typeof t==\\"object\\"&&t&&(a&4&&t.__esModule||a&16&&typeof t.then==\\"function\\"))return t;var c=Object.create(null);r.r(c);var i={};o=o||[null,e({}),e([]),e(e)];for(var n=a&2&&t;typeof n==\\"object\\"&&!~o.indexOf(n);n=e(n))Object.getOwnPropertyNames(n).forEach(u=>i[u]=()=>t[u]);return i.default=()=>t,r.d(c,i),c}})(),(()=>{r.d=(e,o)=>{for(var t in o)r.o(o,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})}})(),(()=>{r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((o,t)=>(r.f[t](e,o),o),[]))})(),(()=>{r.u=e=>\\"\\"+e+\\".\\"+e+\\".js\\"})(),(()=>{r.g=function(){if(typeof globalThis==\\"object\\")return globalThis;try{return this||new Function(\\"return this\\")()}catch(e){if(typeof window==\\"object\\")return window}}()})(),(()=>{r.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o)})(),(()=>{var e={},o=\\"terser-webpack-plugin:\\";r.l=(t,a,c,i)=>{if(e[t]){e[t].push(a);return}var n,u;if(c!==void 0)for(var l=document.getElementsByTagName(\\"script\\"),p=0;p{n.onerror=n.onload=null,clearTimeout(d);var _=e[t];if(delete e[t],n.parentNode&&n.parentNode.removeChild(n),_&&_.forEach(w=>w(m)),h)return h(m)},d=setTimeout(s.bind(null,void 0,{type:\\"timeout\\",target:n}),12e4);n.onerror=s.bind(null,n.onerror),n.onload=s.bind(null,n.onload),u&&document.head.appendChild(n)}})(),(()=>{r.r=e=>{typeof Symbol!=\\"undefined\\"&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\\"Module\\"}),Object.defineProperty(e,\\"__esModule\\",{value:!0})}})(),(()=>{var e;r.g.importScripts&&(e=r.g.location+\\"\\");var o=r.g.document;if(!e&&o&&(o.currentScript&&(e=o.currentScript.src),!e)){var t=o.getElementsByTagName(\\"script\\");t.length&&(e=t[t.length-1].src)}if(!e)throw new Error(\\"Automatic publicPath is not supported in this browser\\");e=e.replace(/#.*$/,\\"\\").replace(/\\\\?.*$/,\\"\\").replace(/\\\\/[^\\\\/]+$/,\\"/\\"),r.p=e})(),(()=>{var e={179:0};r.f.j=(a,c)=>{var i=r.o(e,a)?e[a]:void 0;if(i!==0)if(i)c.push(i[2]);else{var n=new Promise((f,s)=>i=e[a]=[f,s]);c.push(i[2]=n);var u=r.p+r.u(a),l=new Error,p=f=>{if(r.o(e,a)&&(i=e[a],i!==0&&(e[a]=void 0),i)){var s=f&&(f.type===\\"load\\"?\\"missing\\":f.type),d=f&&f.target&&f.target.src;l.message=\\"Loading chunk \\"+a+\` failed. -(\`+s+\\": \\"+d+\\")\\",l.name=\\"ChunkLoadError\\",l.type=s,l.request=d,i[1](l)}};r.l(u,p,\\"chunk-\\"+a,a)}};var o=(a,c)=>{var[i,n,u]=c,l,p,f=0;if(i.some(d=>e[d]!==0)){for(l in n)r.o(n,l)&&(r.m[l]=n[l]);if(u)var s=u(r)}for(a&&a(c);f{var a={791:e=>{/* @preserve*/const o=null;e.exports=function(){const n=2+2;console.log(n+1+2)}}},r={};function c(e){var o=r[e];if(o!==void 0)return o.exports;var _=r[e]={exports:{}};return a[e](_,_.exports,c),_.exports}var t=c(791)})(); -", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\`: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`esbuildMinify\`: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\` and ECMA modules output: assets 1`] = ` -Object { - "main.js": "var __webpack_modules__={791:a=>{a.exports=function(){console.log(7)}}},__webpack_module_cache__={};function __webpack_require__(b){var c=__webpack_module_cache__[b];if(void 0!==c)return c.exports;var d=__webpack_module_cache__[b]={exports:{}};return __webpack_modules__[b](d,d.exports,__webpack_require__),d.exports}var __webpack_exports__=__webpack_require__(791)", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\` and ECMA modules output: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\` and ECMA modules output: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\` and allows to set \`swc\` options: assets 1`] = ` -Object { - "main.js": "(()=>{var __webpack_modules__={791:module=>{module.exports=function(){console.log(7)}}},__webpack_module_cache__={};function __webpack_require__(moduleId){var cachedModule=__webpack_module_cache__[moduleId];if(void 0!==cachedModule)return cachedModule.exports;var module=__webpack_module_cache__[moduleId]={exports:{}};return __webpack_modules__[moduleId](module,module.exports,__webpack_require__),module.exports}var __webpack_exports__=__webpack_require__(791)})()", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\` and allows to set \`swc\` options: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\` and allows to set \`swc\` options: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\` and generate source maps: assets 1`] = ` -Object { - "main.js": "(()=>{var a={791:b=>{b.exports=function(){console.log(7)}}},c={};function d(e){var f=c[e];if(void 0!==f)return f.exports;var g=c[e]={exports:{}};return a[e](g,g.exports,d),g.exports}var h=d(791)})() -//# sourceMappingURL=main.js.map", - "main.js.map": "{\\"version\\":3,\\"file\\":\\"main.js\\",\\"mappings\\":\\"KAAgB,CAAC,GACJ,CAAC,CAAmB,EAE3B,GAAG,CACD,CAAM,EAAK,CAAC,CAOd,CAAC,OAAO,WAAkB,CAAC,OAExB,CAAC,GAAG,CAAC,CAAS,CACvB,CAAC,CAGM,EAKO,CAAwB,aAGnB,CAAmB,CAAC,CAAQ,CAAE,CAAC,GAEpC,CAAC,CAAY,CAAG,CAAwB,CAAC,CAAQ,EACpD,EAAE,MAAmB,CAAS,GAA1B,CAAY,QACR,CAAY,CAAC,OAAO,CAG5B,GAAG,CAAC,CAAM,CAAG,CAAwB,CAAC,CAAQ,GAG7C,OAAO,YAIR,CAAmB,CAAC,CAAQ,EAAE,CAAM,CAAE,CAAM,CAAC,OAAO,CAAE,CAAmB,EAGlE,CAAM,CAAC,OAAO,CACrB,GAOE,CAAC,CAAmB,CAAG,CAAmB,CAAC,GAAG,CAElD,CAAC\\",\\"sources\\":[\\"webpack://terser-webpack-plugin/\\"],\\"sourcesContent\\":[\\"/******/ (() => { // webpackBootstrap\\\\n/******/ \\\\tvar __webpack_modules__ = ({\\\\n\\\\n/***/ 791:\\\\n/***/ ((module) => {\\\\n\\\\n// foo\\\\n/* @preserve*/\\\\n// bar\\\\nconst a = (/* unused pure expression or super */ null && (2 + 2));\\\\n\\\\nmodule.exports = function Foo() {\\\\n const b = 2 + 2;\\\\n console.log(b + 1 + 2);\\\\n};\\\\n\\\\n\\\\n/***/ })\\\\n\\\\n/******/ \\\\t});\\\\n/************************************************************************/\\\\n/******/ \\\\t// The module cache\\\\n/******/ \\\\tvar __webpack_module_cache__ = {};\\\\n/******/ \\\\t\\\\n/******/ \\\\t// The require function\\\\n/******/ \\\\tfunction __webpack_require__(moduleId) {\\\\n/******/ \\\\t\\\\t// Check if module is in cache\\\\n/******/ \\\\t\\\\tvar cachedModule = __webpack_module_cache__[moduleId];\\\\n/******/ \\\\t\\\\tif (cachedModule !== undefined) {\\\\n/******/ \\\\t\\\\t\\\\treturn cachedModule.exports;\\\\n/******/ \\\\t\\\\t}\\\\n/******/ \\\\t\\\\t// Create a new module (and put it into the cache)\\\\n/******/ \\\\t\\\\tvar module = __webpack_module_cache__[moduleId] = {\\\\n/******/ \\\\t\\\\t\\\\t// no module.id needed\\\\n/******/ \\\\t\\\\t\\\\t// no module.loaded needed\\\\n/******/ \\\\t\\\\t\\\\texports: {}\\\\n/******/ \\\\t\\\\t};\\\\n/******/ \\\\t\\\\n/******/ \\\\t\\\\t// Execute the module function\\\\n/******/ \\\\t\\\\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\\\\n/******/ \\\\t\\\\n/******/ \\\\t\\\\t// Return the exports of the module\\\\n/******/ \\\\t\\\\treturn module.exports;\\\\n/******/ \\\\t}\\\\n/******/ \\\\t\\\\n/************************************************************************/\\\\n/******/ \\\\t\\\\n/******/ \\\\t// startup\\\\n/******/ \\\\t// Load entry module and return exports\\\\n/******/ \\\\t// This entry module is referenced by other modules so it can't be inlined\\\\n/******/ \\\\tvar __webpack_exports__ = __webpack_require__(791);\\\\n/******/ \\\\t\\\\n/******/ })()\\\\n;\\"],\\"names\\":[],\\"sourceRoot\\":\\"\\"}", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\` and generate source maps: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\` and generate source maps: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\` and output errors: errors 1`] = ` -Array [ - "Error: broken.js from Terser -Error: error: Unexpected eof", -] -`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\` and output errors: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\`: assets 1`] = ` -Object { - "main.js": "(()=>{var a={791:b=>{b.exports=function(){console.log(7)}}},c={};function d(e){var f=c[e];if(void 0!==f)return f.exports;var g=c[e]={exports:{}};return a[e](g,g.exports,d),g.exports}var h=d(791)})()", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\`: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`swcMinify\`: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\` and ECMA modules output: assets 1`] = ` -Object { - "main.js": "var r={791:r=>{r.exports=function(){console.log(7)}}},o={};(function t(e){var n=o[e];if(void 0!==n)return n.exports;var s=o[e]={exports:{}};return r[e](s,s.exports,t),s.exports})(791);", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\` and ECMA modules output: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\` and ECMA modules output: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\` and allows to set \`terser\` options: assets 1`] = ` -Object { - "main.js": "(()=>{var __webpack_modules__={791:module=>{module.exports=function(){console.log(7)}}},__webpack_module_cache__={};(function __webpack_require__(moduleId){var cachedModule=__webpack_module_cache__[moduleId];if(void 0!==cachedModule)return cachedModule.exports;var module=__webpack_module_cache__[moduleId]={exports:{}};return __webpack_modules__[moduleId](module,module.exports,__webpack_require__),module.exports})(791)})();", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\` and allows to set \`terser\` options: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\` and allows to set \`terser\` options: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\` and extract comments by default: assets 1`] = ` -Object { - "627.627.js": "/*! For license information please see 627.627.js.LICENSE.txt */ -(self.webpackChunkterser_webpack_plugin=self.webpackChunkterser_webpack_plugin||[]).push([[627],{627:e=>{e.exports=Math.random()}}]);", - "627.627.js.LICENSE.txt": "/*! Legal Comment */ - -/** @license Copyright 2112 Moon. **/ -", - "main.js": "/*! For license information please see main.js.LICENSE.txt */ -(()=>{var e,t,r,o,n={900:(e,t,r)=>{r.e(627).then(r.t.bind(r,627,23)),e.exports=Math.random()}},i={};function a(e){var t=i[e];if(void 0!==t)return t.exports;var r=i[e]={exports:{}};return n[e](r,r.exports,a),r.exports}a.m=n,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,a.t=function(r,o){if(1&o&&(r=this(r)),8&o)return r;if(\\"object\\"==typeof r&&r){if(4&o&&r.__esModule)return r;if(16&o&&\\"function\\"==typeof r.then)return r}var n=Object.create(null);a.r(n);var i={};e=e||[null,t({}),t([]),t(t)];for(var u=2&o&&r;\\"object\\"==typeof u&&!~e.indexOf(u);u=t(u))Object.getOwnPropertyNames(u).forEach((e=>i[e]=()=>r[e]));return i.default=()=>r,a.d(n,i),n},a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce(((t,r)=>(a.f[r](e,t),t)),[])),a.u=e=>e+\\".\\"+e+\\".js\\",a.g=function(){if(\\"object\\"==typeof globalThis)return globalThis;try{return this||new Function(\\"return this\\")()}catch(e){if(\\"object\\"==typeof window)return window}}(),a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r={},o=\\"terser-webpack-plugin:\\",a.l=(e,t,n,i)=>{if(r[e])r[e].push(t);else{var u,c;if(void 0!==n)for(var l=document.getElementsByTagName(\\"script\\"),p=0;p{u.onerror=u.onload=null,clearTimeout(d);var n=r[e];if(delete r[e],u.parentNode&&u.parentNode.removeChild(u),n&&n.forEach((e=>e(o))),t)return t(o)},d=setTimeout(f.bind(null,void 0,{type:\\"timeout\\",target:u}),12e4);u.onerror=f.bind(null,u.onerror),u.onload=f.bind(null,u.onload),c&&document.head.appendChild(u)}},a.r=e=>{\\"undefined\\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\\"Module\\"}),Object.defineProperty(e,\\"__esModule\\",{value:!0})},(()=>{var e;a.g.importScripts&&(e=a.g.location+\\"\\");var t=a.g.document;if(!e&&t&&(t.currentScript&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName(\\"script\\");r.length&&(e=r[r.length-1].src)}if(!e)throw new Error(\\"Automatic publicPath is not supported in this browser\\");e=e.replace(/#.*$/,\\"\\").replace(/\\\\?.*$/,\\"\\").replace(/\\\\/[^\\\\/]+$/,\\"/\\"),a.p=e})(),(()=>{var e={179:0};a.f.j=(t,r)=>{var o=a.o(e,t)?e[t]:void 0;if(0!==o)if(o)r.push(o[2]);else{var n=new Promise(((r,n)=>o=e[t]=[r,n]));r.push(o[2]=n);var i=a.p+a.u(t),u=new Error;a.l(i,(r=>{if(a.o(e,t)&&(0!==(o=e[t])&&(e[t]=void 0),o)){var n=r&&(\\"load\\"===r.type?\\"missing\\":r.type),i=r&&r.target&&r.target.src;u.message=\\"Loading chunk \\"+t+\\" failed.\\\\n(\\"+n+\\": \\"+i+\\")\\",u.name=\\"ChunkLoadError\\",u.type=n,u.request=i,o[1](u)}}),\\"chunk-\\"+t,t)}};var t=(t,r)=>{var o,n,[i,u,c]=r,l=0;if(i.some((t=>0!==e[t]))){for(o in u)a.o(u,o)&&(a.m[o]=u[o]);if(c)c(a)}for(t&&t(r);l{var r={791:r=>{r.exports=function(){console.log(7)}}},o={};(function t(e){var n=o[e];if(void 0!==n)return n.exports;var s=o[e]={exports:{}};return r[e](s,s.exports,t),s.exports})(791)})(); -//# sourceMappingURL=main.js.map", - "main.js.map": "{\\"version\\":3,\\"file\\":\\"main.js\\",\\"mappings\\":\\"qBAKAA,EAAOC,QAAU,WAEfC,QAAQC,IAAIC,MCNVC,EAA2B,IAG/B,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBE,IAAjBD,EACH,OAAOA,EAAaP,QAGrB,IAAID,EAASK,EAAyBE,GAAY,CAGjDN,QAAS,IAOV,OAHAS,EAAoBH,GAAUP,EAAQA,EAAOC,QAASK,GAG/CN,EAAOC,SClBWK,CAAoB,M\\",\\"sources\\":[\\"webpack://terser-webpack-plugin/./test/fixtures/entry.js\\",\\"webpack://terser-webpack-plugin/webpack/bootstrap\\",\\"webpack://terser-webpack-plugin/webpack/startup\\"],\\"sourcesContent\\":[\\"// foo\\\\n/* @preserve*/\\\\n// bar\\\\nconst a = 2 + 2;\\\\n\\\\nmodule.exports = function Foo() {\\\\n const b = 2 + 2;\\\\n console.log(b + 1 + 2);\\\\n};\\\\n\\",\\"// The module cache\\\\nvar __webpack_module_cache__ = {};\\\\n\\\\n// The require function\\\\nfunction __webpack_require__(moduleId) {\\\\n\\\\t// Check if module is in cache\\\\n\\\\tvar cachedModule = __webpack_module_cache__[moduleId];\\\\n\\\\tif (cachedModule !== undefined) {\\\\n\\\\t\\\\treturn cachedModule.exports;\\\\n\\\\t}\\\\n\\\\t// Create a new module (and put it into the cache)\\\\n\\\\tvar module = __webpack_module_cache__[moduleId] = {\\\\n\\\\t\\\\t// no module.id needed\\\\n\\\\t\\\\t// no module.loaded needed\\\\n\\\\t\\\\texports: {}\\\\n\\\\t};\\\\n\\\\n\\\\t// Execute the module function\\\\n\\\\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\\\\n\\\\n\\\\t// Return the exports of the module\\\\n\\\\treturn module.exports;\\\\n}\\\\n\\\\n\\",\\"// startup\\\\n// Load entry module and return exports\\\\n// This entry module is referenced by other modules so it can't be inlined\\\\nvar __webpack_exports__ = __webpack_require__(791);\\\\n\\"],\\"names\\":[\\"module\\",\\"exports\\",\\"console\\",\\"log\\",\\"b\\",\\"__webpack_module_cache__\\",\\"__webpack_require__\\",\\"moduleId\\",\\"cachedModule\\",\\"undefined\\",\\"__webpack_modules__\\"],\\"sourceRoot\\":\\"\\"}", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\` and generate source maps: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\` and generate source maps: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\` and keep legal comments when extract comments is disabled: assets 1`] = ` -Object { - "627.627.js": "(self.webpackChunkterser_webpack_plugin=self.webpackChunkterser_webpack_plugin||[]).push([[627],{627:e=>{ -/*! Legal Comment */ -/** @license Copyright 2112 Moon. **/ -e.exports=Math.random()}}]);", - "main.js": "(()=>{var e,t,r,o,n={900:(e,t,r)=>{r.e(627).then(r.t.bind(r,627,23)), -/*! Legal Comment */ -/** - * @preserve Copyright 2009 SomeThirdParty. - * Here is the full license text and copyright - * notice for this file. Note that the notice can span several - * lines and is only terminated by the closing star and slash: - */ -/** - * Utility functions for the foo package. - * @license Apache-2.0 - */ -/*! Legal Foo */ -// @lic -e.exports=Math.random()}},i={};function a(e){var t=i[e];if(void 0!==t)return t.exports;var r=i[e]={exports:{}};return n[e](r,r.exports,a),r.exports}a.m=n,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,a.t=function(r,o){if(1&o&&(r=this(r)),8&o)return r;if(\\"object\\"==typeof r&&r){if(4&o&&r.__esModule)return r;if(16&o&&\\"function\\"==typeof r.then)return r}var n=Object.create(null);a.r(n);var i={};e=e||[null,t({}),t([]),t(t)];for(var u=2&o&&r;\\"object\\"==typeof u&&!~e.indexOf(u);u=t(u))Object.getOwnPropertyNames(u).forEach((e=>i[e]=()=>r[e]));return i.default=()=>r,a.d(n,i),n},a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce(((t,r)=>(a.f[r](e,t),t)),[])),a.u=e=>e+\\".\\"+e+\\".js\\",a.g=function(){if(\\"object\\"==typeof globalThis)return globalThis;try{return this||new Function(\\"return this\\")()}catch(e){if(\\"object\\"==typeof window)return window}}(),a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r={},o=\\"terser-webpack-plugin:\\",a.l=(e,t,n,i)=>{if(r[e])r[e].push(t);else{var u,c;if(void 0!==n)for(var l=document.getElementsByTagName(\\"script\\"),p=0;p{u.onerror=u.onload=null,clearTimeout(d);var n=r[e];if(delete r[e],u.parentNode&&u.parentNode.removeChild(u),n&&n.forEach((e=>e(o))),t)return t(o)},d=setTimeout(f.bind(null,void 0,{type:\\"timeout\\",target:u}),12e4);u.onerror=f.bind(null,u.onerror),u.onload=f.bind(null,u.onload),c&&document.head.appendChild(u)}},a.r=e=>{\\"undefined\\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\\"Module\\"}),Object.defineProperty(e,\\"__esModule\\",{value:!0})},(()=>{var e;a.g.importScripts&&(e=a.g.location+\\"\\");var t=a.g.document;if(!e&&t&&(t.currentScript&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName(\\"script\\");r.length&&(e=r[r.length-1].src)}if(!e)throw new Error(\\"Automatic publicPath is not supported in this browser\\");e=e.replace(/#.*$/,\\"\\").replace(/\\\\?.*$/,\\"\\").replace(/\\\\/[^\\\\/]+$/,\\"/\\"),a.p=e})(),(()=>{var e={179:0};a.f.j=(t,r)=>{var o=a.o(e,t)?e[t]:void 0;if(0!==o)if(o)r.push(o[2]);else{var n=new Promise(((r,n)=>o=e[t]=[r,n]));r.push(o[2]=n);var i=a.p+a.u(t),u=new Error;a.l(i,(r=>{if(a.o(e,t)&&(0!==(o=e[t])&&(e[t]=void 0),o)){var n=r&&(\\"load\\"===r.type?\\"missing\\":r.type),i=r&&r.target&&r.target.src;u.message=\\"Loading chunk \\"+t+\\" failed.\\\\n(\\"+n+\\": \\"+i+\\")\\",u.name=\\"ChunkLoadError\\",u.type=n,u.request=i,o[1](u)}}),\\"chunk-\\"+t,t)}};var t=(t,r)=>{var o,n,[i,u,c]=r,l=0;if(i.some((t=>0!==e[t]))){for(o in u)a.o(u,o)&&(a.m[o]=u[o]);if(c)c(a)}for(t&&t(r);l{var r={791:r=>{r.exports=function(){console.log(7)}}},o={};(function t(e){var n=o[e];if(void 0!==n)return n.exports;var s=o[e]={exports:{}};return r[e](s,s.exports,t),s.exports})(791)})();", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\`: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`terserMinify\`: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`uglifyJsMinify\` and allows to set \`uglify-js\` options: assets 1`] = ` -Object { - "main.js": "!function(){var __webpack_modules__={791:function(module){module.exports=function(){console.log(7)}}},__webpack_module_cache__={};(function __webpack_require__(moduleId){var module=__webpack_module_cache__[moduleId];if(void 0!==module)return module.exports;module=__webpack_module_cache__[moduleId]={exports:{}};return __webpack_modules__[moduleId](module,module.exports,__webpack_require__),module.exports})(791)}();", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`uglifyJsMinify\` and allows to set \`uglify-js\` options: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`uglifyJsMinify\` and allows to set \`uglify-js\` options: warnings 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`uglifyJsMinify\` and extract comments by default: assets 1`] = ` -Object { - "627.627.js": "/*! For license information please see 627.627.js.LICENSE.txt */ -(self.webpackChunkterser_webpack_plugin=self.webpackChunkterser_webpack_plugin||[]).push([[627],{627:function(e){e.exports=Math.random()}}]);", - "627.627.js.LICENSE.txt": "/*! Legal Comment */ - -/** @license Copyright 2112 Moon. **/ -", - "main.js": "/*! For license information please see main.js.LICENSE.txt */ -!function(){var i,u,l,p,r={900:function(e,t,r){r.e(627).then(r.t.bind(r,627,23)),e.exports=Math.random()}},n={};function s(e){var t=n[e];if(void 0!==t)return t.exports;t=n[e]={exports:{}};return r[e](t,t.exports,s),t.exports}s.m=r,u=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},s.t=function(t,e){if(1&e&&(t=this(t)),8&e)return t;if(\\"object\\"==typeof t&&t){if(4&e&&t.__esModule)return t;if(16&e&&\\"function\\"==typeof t.then)return t}var r=Object.create(null);s.r(r);var n={};i=i||[null,u({}),u([]),u(u)];for(var o=2&e&&t;\\"object\\"==typeof o&&!~i.indexOf(o);o=u(o))Object.getOwnPropertyNames(o).forEach(function(e){n[e]=function(){return t[e]}});return n.default=function(){return t},s.d(r,n),r},s.d=function(e,t){for(var r in t)s.o(t,r)&&!s.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},s.f={},s.e=function(r){return Promise.all(Object.keys(s.f).reduce(function(e,t){return s.f[t](r,e),e},[]))},s.u=function(e){return e+\\".\\"+e+\\".js\\"},s.g=function(){if(\\"object\\"==typeof globalThis)return globalThis;try{return this||new Function(\\"return this\\")()}catch(e){if(\\"object\\"==typeof window)return window}}(),s.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},l={},p=\\"terser-webpack-plugin:\\",s.l=function(n,e,t,r){if(l[n])l[n].push(e);else{var o,i;if(void 0!==t)for(var u=document.getElementsByTagName(\\"script\\"),c=0;c{var e={791:o=>{o.exports=function(){console.log(7)}}},n={};(function o(r){var t=n[r];if(void 0!==t)return t.exports;t=n[r]={exports:{}};return e[r](t,t.exports,o),t.exports})(791)})();", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`uglifyJsMinify\` and output warnings: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`uglifyJsMinify\` and output warnings: warnings 1`] = ` -Array [ - "Warning: WARN: Condition left of && always false [main.js:10,10]", - "Warning: WARN: Dropping duplicated definition of variable k [main.js:33,15]", - "Warning: WARN: Dropping unused variable f [main.js:10,6]", - "Warning: WARN: Side effects in initialization of unused variable d [main.js:51,14]", -] -`; - -exports[`minify option should work using when the \`minify\` option is \`uglifyJsMinify\`: assets 1`] = ` -Object { - "main.js": "!function(){var t={791:function(o){o.exports=function(){console.log(7)}}},e={};(function o(n){var r=e[n];if(void 0!==r)return r.exports;r=e[n]={exports:{}};return t[n](r,r.exports,o),r.exports})(791)}();", -} -`; - -exports[`minify option should work using when the \`minify\` option is \`uglifyJsMinify\`: errors 1`] = `Array []`; - -exports[`minify option should work using when the \`minify\` option is \`uglifyJsMinify\`: warnings 1`] = `Array []`; - -exports[`minify option should work when the "parallel" option is "false": assets 1`] = ` -Object { - "main.js": "(()=>{\\"use strict\\";console.log(\\"HERE\\")})();", -} -`; - -exports[`minify option should work when the "parallel" option is "false": errors 1`] = `Array []`; - -exports[`minify option should work when the "parallel" option is "false": warnings 1`] = `Array []`; - -exports[`minify option should work when the "parallel" option is "true": assets 1`] = ` -Object { - "main.js": "(()=>{\\"use strict\\";console.log(\\"HERE\\")})();", -} -`; - -exports[`minify option should work when the "parallel" option is "true": errors 1`] = `Array []`; - -exports[`minify option should work when the "parallel" option is "true": warnings 1`] = `Array []`; - -exports[`minify option should work with "terser" minimizer: assets 1`] = ` -Object { - "main.js": "(()=>{\\"use strict\\";console.log(\\"HERE\\")})();", -} -`; - -exports[`minify option should work with "terser" minimizer: errors 1`] = `Array []`; - -exports[`minify option should work with "terser" minimizer: warnings 1`] = `Array []`; - -exports[`minify option should work with "uglify-js" minimizer: assets 1`] = ` -Object { - "main.js": "!function(){var r={293:function(e){e.exports=function(){var baz=document.getElementById(\\"root\\").innerHTML;document.getElementById(\\"demo\\").innerHTML=\\"Paragraph changed.\\"+baz}}},o={};(function e(n){var t=o[n];if(void 0!==t)return t.exports;t=o[n]={exports:{}};return r[n](t,t.exports,e),t.exports})(293)}();", -} -`; - -exports[`minify option should work with "uglify-js" minimizer: errors 1`] = `Array []`; - -exports[`minify option should work with "uglify-js" minimizer: warnings 1`] = `Array []`; - -exports[`minify option should work with custom minimize function and support warnings and errors: errors 1`] = ` -Array [ - "Error: Error 1 [main.js]", - "Error: Error 2", - "Error: Error 3 [main.js]", - "Error: Error 4 [foo.js]", - "Error: Error 5 [foo.js]", - "Error: Error 6 [foo.js:1,1]", -] -`; - -exports[`minify option should work with custom minimize function and support warnings and errors: warnings 1`] = ` -Array [ - "Warning: Error: Warning 1", - "Warning: Warnings 2", -] -`; - -exports[`minify option should work with source maps: assets 1`] = ` -Object { - "main.js": "(()=>{\\"use strict\\";console.log(\\"HERE\\")})(); -//# sourceMappingURL=main.js.map", - "main.js.map": "{\\"version\\":3,\\"file\\":\\"main.js\\",\\"mappings\\":\\"mBAcAA,QAAAC,IAAA\\",\\"sources\\":[\\"webpack://terser-webpack-plugin/./test/fixtures/minify/es6.js\\"],\\"sourcesContent\\":[\\"class Point {\\\\n constructor(x, y) {\\\\n this.x = x;\\\\n this.y = y;\\\\n }\\\\n\\\\n static distance(a, b) {\\\\n const dx = a.x - b.x;\\\\n const dy = a.y - b.y;\\\\n\\\\n return Math.hypot(dx, dy);\\\\n }\\\\n}\\\\n\\\\nconsole.log('HERE');\\\\n\\\\nexport default Point;\\\\n\\"],\\"names\\":[\\"console\\",\\"log\\"],\\"sourceRoot\\":\\"\\"}", -} -`; - -exports[`minify option should work with source maps: errors 1`] = `Array []`; - -exports[`minify option should work with source maps: warnings 1`] = `Array []`; - -exports[`minify option should work: assets 1`] = ` -Object { - "main.js": "(()=>{\\"use strict\\";console.log(\\"HERE\\")})();", -} -`; - -exports[`minify option should work: errors 1`] = `Array []`; - -exports[`minify option should work: warnings 1`] = `Array []`; +exports[`minify option should work with multiple custom minimize functions and source map: warnings 1`] = `Array []`; diff --git a/test/fixtures/entry.js b/test/fixtures/entry.js index 575daafe..a9d86f86 100644 --- a/test/fixtures/entry.js +++ b/test/fixtures/entry.js @@ -5,5 +5,8 @@ const a = 2 + 2; module.exports = function Foo() { const b = 2 + 2; + throw new Error('test'); console.log(b + 1 + 2); }; + +module.exports(); diff --git a/test/helpers/getCompiler.js b/test/helpers/getCompiler.js index 19c31e10..13929adf 100644 --- a/test/helpers/getCompiler.js +++ b/test/helpers/getCompiler.js @@ -25,7 +25,7 @@ export default function getCompiler(options = {}) { } ); - compiler.outputFileSystem = createFsFromVolume(new Volume()); + // compiler.outputFileSystem = createFsFromVolume(new Volume()); return compiler; } diff --git a/test/minify-option.test.js b/test/minify-option.test.js index 6fe4a16d..051da25f 100644 --- a/test/minify-option.test.js +++ b/test/minify-option.test.js @@ -228,12 +228,11 @@ describe("minify option", () => { expect(getWarnings(stats)).toMatchSnapshot("warnings"); }); - it('should work with "uglify-js" minimizer', async () => { + it("should work with custom minimize function and support warnings and errors", async () => { const compiler = getCompiler({ - target: ["es5", "web"], - entry: path.resolve(__dirname, "./fixtures/minify/es5.js"), + entry: path.resolve(__dirname, "./fixtures/minify/es6.js"), output: { - path: path.resolve(__dirname, "./dist-uglify-js"), + path: path.resolve(__dirname, "./dist-terser"), filename: "[name].js", chunkFilename: "[id].[name].js", }, @@ -241,41 +240,43 @@ describe("minify option", () => { new TerserPlugin({ minify(file) { - // eslint-disable-next-line global-require - return require("uglify-js").minify(file, { - mangle: { - reserved: ["baz"], - }, - }); + const isOldNodeJs = process.version.match(/^v(\d+)/)[1] === "10"; + const [[, code]] = Object.entries(file); + + return { + code, + warnings: [ + isOldNodeJs + ? new Error("Warning 1").toString() + : new Error("Warning 1"), + "Warnings 2", + ], + errors: [ + isOldNodeJs ? "Error 1 [main.js]" : new Error("Error 1"), + "Error 2", + { message: "Error 3" }, + { message: "Error 4", filename: "foo.js" }, + { message: "Error 5", filename: "foo.js", line: 0, col: 0 }, + { message: "Error 6", filename: "foo.js", line: 1, col: 1 }, + ], + }; }, }).apply(compiler); const stats = await compile(compiler); - expect(readsAssets(compiler, stats)).toMatchSnapshot("assets"); expect(getErrors(stats)).toMatchSnapshot("errors"); expect(getWarnings(stats)).toMatchSnapshot("warnings"); }); - it('should work with "terser" minimizer', async () => { - const compiler = getCompiler({ - entry: path.resolve(__dirname, "./fixtures/minify/es6.js"), - output: { - path: path.resolve(__dirname, "./dist-terser"), - filename: "[name].js", - chunkFilename: "[id].[name].js", - }, - }); + it("should work with multiple custom minimize functions", async () => { + const compiler = getCompiler(); new TerserPlugin({ - minify(file) { - // eslint-disable-next-line global-require - return require("terser").minify(file, { - mangle: { - reserved: ["baz"], - }, - }); - }, + minify: [ + TerserPlugin.terserMinify, + TerserPlugin.swcMinify, + ] }).apply(compiler); const stats = await compile(compiler); @@ -285,43 +286,66 @@ describe("minify option", () => { expect(getWarnings(stats)).toMatchSnapshot("warnings"); }); - it("should work with custom minimize function and support warnings and errors", async () => { + it.only("should work with multiple custom minimize functions and source map", async () => { const compiler = getCompiler({ - entry: path.resolve(__dirname, "./fixtures/minify/es6.js"), - output: { - path: path.resolve(__dirname, "./dist-terser"), - filename: "[name].js", - chunkFilename: "[id].[name].js", - }, + devtool: "source-map" }); new TerserPlugin({ - minify(file) { - const isOldNodeJs = process.version.match(/^v(\d+)/)[1] === "10"; - const [[, code]] = Object.entries(file); + minify: [ + TerserPlugin.terserMinify, + TerserPlugin.uglifyJsMinify, + ] + }).apply(compiler); - return { - code, - warnings: [ - isOldNodeJs - ? new Error("Warning 1").toString() - : new Error("Warning 1"), - "Warnings 2", - ], - errors: [ - isOldNodeJs ? "Error 1 [main.js]" : new Error("Error 1"), - "Error 2", - { message: "Error 3" }, - { message: "Error 4", filename: "foo.js" }, - { message: "Error 5", filename: "foo.js", line: 0, col: 0 }, - { message: "Error 6", filename: "foo.js", line: 1, col: 1 }, - ], - }; + const stats = await compile(compiler); + + expect(readsAssets(compiler, stats)).toMatchSnapshot("assets"); + expect(getErrors(stats)).toMatchSnapshot("errors"); + expect(getWarnings(stats)).toMatchSnapshot("warnings"); + }); + + it("should work with multiple custom minimize functions and single options", async () => { + const compiler = getCompiler(); + + new TerserPlugin({ + minify: [ + TerserPlugin.terserMinify, + TerserPlugin.swcMinify, + ], + terserOptions: { + mangle: false, }, }).apply(compiler); const stats = await compile(compiler); + expect(readsAssets(compiler, stats)).toMatchSnapshot("assets"); + expect(getErrors(stats)).toMatchSnapshot("errors"); + expect(getWarnings(stats)).toMatchSnapshot("warnings"); + }); + + it("should work with multiple custom minimize functions and multiple options", async () => { + const compiler = getCompiler(); + + new TerserPlugin({ + minify: [ + TerserPlugin.terserMinify, + TerserPlugin.swcMinify, + ], + terserOptions: [ + { + mangle: false, + }, + { + mangle: false, + } + ], + }).apply(compiler); + + const stats = await compile(compiler); + + expect(readsAssets(compiler, stats)).toMatchSnapshot("assets"); expect(getErrors(stats)).toMatchSnapshot("errors"); expect(getWarnings(stats)).toMatchSnapshot("warnings"); });