How to use Terser with webpack
Solution 1
optimization: {
removeAvailableModules: false,
minimizer: [
new TerserJSPlugin({
terserOptions: {
parse: {
// we want terser to parse ecma 8 code. However, we don't want it
// to apply any minfication steps that turns valid ecma 5 code
// into invalid ecma 5 code. This is why the 'compress' and 'output'
// sections only apply transformations that are ecma 5 safe
// https://github.com/facebook/create-react-app/pull/4234
ecma: 8
},
compress: {
ecma : 5,
warnings : false,
// Disabled because of an issue with Uglify breaking seemingly valid code:
// https://github.com/facebook/create-react-app/issues/2376
// Pending further investigation:
// https://github.com/mishoo/UglifyJS2/issues/2011
comparisons: false,
// Disabled because of an issue with Terser breaking valid code:
// https://github.com/facebook/create-react-app/issues/5250
// Pending futher investigation:
// https://github.com/terser-js/terser/issues/120
inline : 2
},
mangle: {
safari10: true
},
output: {
ecma : 5,
comments : false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebook/create-react-app/issues/2488
ascii_only: true
}
},
cache: true,
parallel: true,
sourceMap: true, // Must be set to true if using source-maps in production
}),
new OptimizeCSSAssetsPlugin({})
],
runtimeChunk: true
},
Solution 2
As of webpack 5 all u need is to add this syntax to extend existing minimizers which is terser one of them. https://webpack.js.org/plugins/css-minimizer-webpack-plugin/
minimizer: [
// this `...` do that for you
`...`,
// your other minimizers goes here
new CssMinimizerPlugin({
exclude: /(node_modules)/,
}),
],
Thomas Bishop
Updated on June 13, 2022Comments
-
Thomas Bishop almost 2 years
I am using Webpack 6.10.2 with Vue 3.9.3. This install uses Uglify.js which throws an error when I run
npm run build
because it cannot work with ES6.To get round this, I have removed Uglify form
webpack.config.js
as recommended and I have attempted to use Terser to minify the JS in production. Every attempt I have made results in errors because I haven't added the syntax right. When I remove Terser, the app compiles but obviously without JS minification so I am doing something wrong with the syntax inwebpack.config.js
.Can anyone tell me where I am going wrong.
Thank you
webpack.config.js :
var path = require('path') var webpack = require('webpack') const TerserPlugin = require('terser-webpack-plugin') module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, './dist'), publicPath: '/dist/', filename: 'build.js' }, module: { rules: [ { test: /\.css$/, use: [ 'vue-style-loader', 'css-loader' ], }, { test: /\.scss$/, use: [ 'vue-style-loader', 'css-loader', 'sass-loader' ], }, { test: /\.sass$/, use: [ 'vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax' ], }, { test: /\.vue$/, loader: 'vue-loader', options: { loaders: { // Since sass-loader (weirdly) has SCSS as its default parse mode, we map // the "scss" and "sass" values for the lang attribute to the right configs here. // other preprocessors should work out of the box, no loader config like this necessary. 'scss': [ 'vue-style-loader', 'css-loader', 'sass-loader' ], 'sass': [ 'vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax' ] } // other vue-loader options go here } }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }, { test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader', options: { name: '[name].[ext]?[hash]' } } ] }, resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js' }, extensions: ['*', '.js', '.vue', '.json'] }, devServer: { historyApiFallback: true, noInfo: true, overlay: true }, performance: { hints: false }, devtool: '#eval-source-map' } if (process.env.NODE_ENV === 'production') { module.exports = { optimization: ) minimizer: [new TerserPlugin()], }, module.exports.devtool = '#source-map' module.exports.plugins = (module.exports.plugins || []).concat([ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"production"' } }), new webpack.LoaderOptionsPlugin({ minimize: true }) ]) }
package.json :
{ "name": "vue_frontend", "description": "A Vue.js project", "version": "1.0.0", "author": "Thomas Bishop <[email protected]>", "license": "MIT", "private": true, "scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot", "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" }, "dependencies": { "buefy": "^0.7.10", "vue": "^2.5.11", "vue-router": "^3.0.7" }, "browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ], "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-env": "^1.6.0", "babel-preset-stage-3": "^6.24.1", "cross-env": "^5.0.5", "css-loader": "^0.28.7", "file-loader": "^1.1.4", "node-sass": "^4.5.3", "sass-loader": "^6.0.6", "terser-webpack-plugin": "^1.4.1", "vue-loader": "^13.0.5", "vue-template-compiler": "^2.4.4", "webpack": "^3.6.0", "webpack-dev-server": "^2.9.1" } }