Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 106 additions & 36 deletions packages/@vue/cli-service/lib/config/terserOptions.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,110 @@
module.exports = options => ({
terserOptions: {
compress: {
// turn off flags with small gains to speed up minification
arrows: false,
collapse_vars: false, // 0.3kb
comparisons: false,
computed_props: false,
hoist_funs: false,
hoist_props: false,
hoist_vars: false,
inline: false,
loops: false,
negate_iife: false,
properties: false,
reduce_funcs: false,
reduce_vars: false,
switches: false,
toplevel: false,
typeofs: false,

// a few flags with noticeable gains/speed ratio
// numbers based on out of the box vendor bundle
booleans: true, // 0.7kb
if_return: true, // 0.4kb
sequences: true, // 0.7kb
unused: true, // 2.3kb

// required features to drop conditional branches
conditionals: true,
dead_code: true,
evaluate: true
// @ts-check
const TerserPlugin = require('terser-webpack-plugin')

const genTerserOptions = (defaultOptions, options) => {
const userOptions = options.terser && options.terser.terserOptions
// user's config is first
return {
...defaultOptions,
...userOptions
}
}

const terserMinify = (options) => ({
terserOptions: genTerserOptions(
{
compress: {
// turn off flags with small gains to speed up minification
arrows: false,
collapse_vars: false, // 0.3kb
comparisons: false,
computed_props: false,
hoist_funs: false,
hoist_props: false,
hoist_vars: false,
inline: false,
loops: false,
negate_iife: false,
properties: false,
reduce_funcs: false,
reduce_vars: false,
switches: false,
toplevel: false,
typeofs: false,

// a few flags with noticeable gains/speed ratio
// numbers based on out of the box vendor bundle
booleans: true, // 0.7kb
if_return: true, // 0.4kb
sequences: true, // 0.7kb
unused: true, // 2.3kb

// required features to drop conditional branches
conditionals: true,
dead_code: true,
evaluate: true
},
mangle: {
safari10: true
}
},
mangle: {
safari10: true
}
},
options
),
parallel: options.parallel,
extractComments: false
})

// `terserOptions` options will be passed to `esbuild`
// Link to options - https://esbuild.github.io/api/#minify
const esbuildMinify = (options) => ({
minify: TerserPlugin.esbuildMinify,
terserOptions: genTerserOptions(
{
minify: false,
minifyWhitespace: true,
minifyIdentifiers: false,
minifySyntax: true
},
options
),
parallel: options.parallel
})

// `terserOptions` options will be passed to `swc` (`@swc/core`)
// Link to options - https://swc.rs/docs/config-js-minify
const swcMinify = (options) => ({
minify: TerserPlugin.swcMinify,
terserOptions: genTerserOptions(
{
compress: {
unused: true
},
mangle: true
},
options
),
parallel: options.parallel
})

// `terserOptions` options will be passed to `uglify-js`
// Link to options - https://github.com/mishoo/UglifyJS#minify-options
const uglifyJsMinify = (options) => ({
minify: TerserPlugin.uglifyJsMinify,
terserOptions: genTerserOptions({}, options),
parallel: options.parallel
})

// Currently we do not allow custom minify function
const getMinify = (options) => {
const { minify = 'terser' } = options.terser || {}

const minifyMap = {
terser: terserMinify,
esbuild: esbuildMinify,
swc: swcMinify,
uglifyJs: uglifyJsMinify
}
return minifyMap[minify](options)
}

module.exports = getMinify
6 changes: 6 additions & 0 deletions packages/@vue/cli-service/lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ const schema = createSchema(joi => joi.object({
lintOnSave: joi.any().valid(true, false, 'error', 'warning', 'default'),
pwa: joi.object(),

// terser
terser: joi.object({
minify: joi.string().valid('terser', 'esbuild', 'swc', 'uglifyJs'),
terserOptions: joi.object()
}),

// 3rd party plugin options
pluginOptions: joi.object()
}))
Expand Down
27 changes: 27 additions & 0 deletions packages/@vue/cli-service/types/ProjectOptions.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import ChainableWebpackConfig = require('webpack-chain')
import { Configuration as WebpackOptions } from 'webpack'

type PredefinedOptions<T> = T & { [key: string]: any }

type PageEntry = string | string[];

interface PageConfig {
Expand Down Expand Up @@ -153,6 +155,31 @@ interface ProjectOptions {
*/
pwa?: object;

/**
* set terser-webpack-plugin minify and terserOptions
*/
terser?: {
/**
* 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
*
* In the non-terser case, you should install the corresponding package (eg. `npm i esbuild -D`)
*
*/
minify: 'terser' | 'esbuild' | 'swc' | 'uglifyJs';
/**
* `terserOptions` options will be passed to minify
*
* [All options for `terser`](https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions)
*
* [All options for `esbuild`](https://github.com/evanw/esbuild/blob/master/lib/shared/types.ts#L160-L174)
*
* [All options for `swc`](https://swc.rs/docs/config-js-minify)
*
* [All options for `uglifyJs`](https://github.com/mishoo/UglifyJS#minify-options)
*/
terserOptions?: PredefinedOptions<import("terser").MinifyOptions>;
};

/**
* 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
*/
Expand Down