Skip to content

Commit 9aeafc0

Browse files
authored
feat: add a top-level terser option to allow users to customize the minifier (#6752)
1 parent 1004020 commit 9aeafc0

File tree

3 files changed

+139
-36
lines changed

3 files changed

+139
-36
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,110 @@
1-
module.exports = options => ({
2-
terserOptions: {
3-
compress: {
4-
// turn off flags with small gains to speed up minification
5-
arrows: false,
6-
collapse_vars: false, // 0.3kb
7-
comparisons: false,
8-
computed_props: false,
9-
hoist_funs: false,
10-
hoist_props: false,
11-
hoist_vars: false,
12-
inline: false,
13-
loops: false,
14-
negate_iife: false,
15-
properties: false,
16-
reduce_funcs: false,
17-
reduce_vars: false,
18-
switches: false,
19-
toplevel: false,
20-
typeofs: false,
21-
22-
// a few flags with noticeable gains/speed ratio
23-
// numbers based on out of the box vendor bundle
24-
booleans: true, // 0.7kb
25-
if_return: true, // 0.4kb
26-
sequences: true, // 0.7kb
27-
unused: true, // 2.3kb
28-
29-
// required features to drop conditional branches
30-
conditionals: true,
31-
dead_code: true,
32-
evaluate: true
1+
// @ts-check
2+
const TerserPlugin = require('terser-webpack-plugin')
3+
4+
const genTerserOptions = (defaultOptions, options) => {
5+
const userOptions = options.terser && options.terser.terserOptions
6+
// user's config is first
7+
return {
8+
...defaultOptions,
9+
...userOptions
10+
}
11+
}
12+
13+
const terserMinify = (options) => ({
14+
terserOptions: genTerserOptions(
15+
{
16+
compress: {
17+
// turn off flags with small gains to speed up minification
18+
arrows: false,
19+
collapse_vars: false, // 0.3kb
20+
comparisons: false,
21+
computed_props: false,
22+
hoist_funs: false,
23+
hoist_props: false,
24+
hoist_vars: false,
25+
inline: false,
26+
loops: false,
27+
negate_iife: false,
28+
properties: false,
29+
reduce_funcs: false,
30+
reduce_vars: false,
31+
switches: false,
32+
toplevel: false,
33+
typeofs: false,
34+
35+
// a few flags with noticeable gains/speed ratio
36+
// numbers based on out of the box vendor bundle
37+
booleans: true, // 0.7kb
38+
if_return: true, // 0.4kb
39+
sequences: true, // 0.7kb
40+
unused: true, // 2.3kb
41+
42+
// required features to drop conditional branches
43+
conditionals: true,
44+
dead_code: true,
45+
evaluate: true
46+
},
47+
mangle: {
48+
safari10: true
49+
}
3350
},
34-
mangle: {
35-
safari10: true
36-
}
37-
},
51+
options
52+
),
3853
parallel: options.parallel,
3954
extractComments: false
4055
})
56+
57+
// `terserOptions` options will be passed to `esbuild`
58+
// Link to options - https://esbuild.github.io/api/#minify
59+
const esbuildMinify = (options) => ({
60+
minify: TerserPlugin.esbuildMinify,
61+
terserOptions: genTerserOptions(
62+
{
63+
minify: false,
64+
minifyWhitespace: true,
65+
minifyIdentifiers: false,
66+
minifySyntax: true
67+
},
68+
options
69+
),
70+
parallel: options.parallel
71+
})
72+
73+
// `terserOptions` options will be passed to `swc` (`@swc/core`)
74+
// Link to options - https://swc.rs/docs/config-js-minify
75+
const swcMinify = (options) => ({
76+
minify: TerserPlugin.swcMinify,
77+
terserOptions: genTerserOptions(
78+
{
79+
compress: {
80+
unused: true
81+
},
82+
mangle: true
83+
},
84+
options
85+
),
86+
parallel: options.parallel
87+
})
88+
89+
// `terserOptions` options will be passed to `uglify-js`
90+
// Link to options - https://github.com/mishoo/UglifyJS#minify-options
91+
const uglifyJsMinify = (options) => ({
92+
minify: TerserPlugin.uglifyJsMinify,
93+
terserOptions: genTerserOptions({}, options),
94+
parallel: options.parallel
95+
})
96+
97+
// Currently we do not allow custom minify function
98+
const getMinify = (options) => {
99+
const { minify = 'terser' } = options.terser || {}
100+
101+
const minifyMap = {
102+
terser: terserMinify,
103+
esbuild: esbuildMinify,
104+
swc: swcMinify,
105+
uglifyJs: uglifyJsMinify
106+
}
107+
return minifyMap[minify](options)
108+
}
109+
110+
module.exports = getMinify

packages/@vue/cli-service/lib/options.js

+6
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ const schema = createSchema(joi => joi.object({
5959
lintOnSave: joi.any().valid(true, false, 'error', 'warning', 'default'),
6060
pwa: joi.object(),
6161

62+
// terser
63+
terser: joi.object({
64+
minify: joi.string().valid('terser', 'esbuild', 'swc', 'uglifyJs'),
65+
terserOptions: joi.object()
66+
}),
67+
6268
// 3rd party plugin options
6369
pluginOptions: joi.object()
6470
}))

packages/@vue/cli-service/types/ProjectOptions.d.ts

+27
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import ChainableWebpackConfig = require('webpack-chain')
22
import { Configuration as WebpackOptions } from 'webpack'
33

4+
type PredefinedOptions<T> = T & { [key: string]: any }
5+
46
type PageEntry = string | string[];
57

68
interface PageConfig {
@@ -153,6 +155,31 @@ interface ProjectOptions {
153155
*/
154156
pwa?: object;
155157

158+
/**
159+
* set terser-webpack-plugin minify and terserOptions
160+
*/
161+
terser?: {
162+
/**
163+
* Supported minify: [terser](https://github.com/webpack-contrib/terser-webpack-plugin#minify), [esbuild](https://github.com/webpack-contrib/terser-webpack-plugin#esbuild), [swc](https://github.com/webpack-contrib/terser-webpack-plugin#swc), [uglifyJs](https://github.com/webpack-contrib/terser-webpack-plugin#uglify-js). currently we do not allow custom minify function
164+
*
165+
* In the non-terser case, you should install the corresponding package (eg. `npm i esbuild -D`)
166+
*
167+
*/
168+
minify: 'terser' | 'esbuild' | 'swc' | 'uglifyJs';
169+
/**
170+
* `terserOptions` options will be passed to minify
171+
*
172+
* [All options for `terser`](https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions)
173+
*
174+
* [All options for `esbuild`](https://github.com/evanw/esbuild/blob/master/lib/shared/types.ts#L160-L174)
175+
*
176+
* [All options for `swc`](https://swc.rs/docs/config-js-minify)
177+
*
178+
* [All options for `uglifyJs`](https://github.com/mishoo/UglifyJS#minify-options)
179+
*/
180+
terserOptions?: PredefinedOptions<import("terser").MinifyOptions>;
181+
};
182+
156183
/**
157184
* This is an object that doesn't go through any schema validation, so it can be used to pass arbitrary options to 3rd party plugins
158185
*/

0 commit comments

Comments
 (0)