Top Related Projects
🗜 JavaScript parser, mangler and compressor toolkit for ES6+
JavaScript parser / mangler / compressor / beautifier toolkit
:scissors: An ES6+ aware minifier based on the Babel toolchain (beta)
A JavaScript checker and optimizer.
An extremely fast bundler for the web
Rust-based platform for the Web
Quick Overview
Terser-webpack-plugin is a plugin for webpack that uses Terser to minify JavaScript files. It's designed to optimize and compress JavaScript code, reducing file sizes and improving load times for web applications.
Pros
- Highly configurable, allowing fine-tuning of minification options
- Supports ES6+ syntax, making it suitable for modern JavaScript projects
- Integrates seamlessly with webpack, a popular module bundler
- Offers parallel processing for improved performance on multi-core CPUs
Cons
- Can significantly increase build times, especially for large projects
- May introduce subtle bugs if not configured correctly
- Learning curve for advanced configuration options
- Occasional compatibility issues with certain JavaScript features or libraries
Code Examples
- Basic usage in webpack configuration:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [new TerserPlugin()],
},
};
- Custom configuration for more control:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true,
},
},
}),
],
},
};
- Enabling source maps:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
sourceMap: true,
}),
],
},
};
Getting Started
To use terser-webpack-plugin in your project:
-
Install the plugin:
npm install terser-webpack-plugin --save-dev
-
Add it to your webpack configuration:
const TerserPlugin = require('terser-webpack-plugin'); module.exports = { optimization: { minimizer: [new TerserPlugin()], }, };
-
Run your webpack build as usual. The plugin will automatically minify your JavaScript output.
Competitor Comparisons
🗜 JavaScript parser, mangler and compressor toolkit for ES6+
Pros of terser
- Standalone JavaScript minifier, usable in various environments
- More flexible and customizable for non-webpack projects
- Can be used as a library in Node.js applications
Cons of terser
- Requires manual integration with webpack builds
- Less optimized for webpack-specific use cases
- May need additional configuration for optimal webpack performance
Code Comparison
terser:
import { minify } from "terser";
const result = await minify(code, {
mangle: true,
compress: {
dead_code: true,
},
});
terser-webpack-plugin:
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
optimization: {
minimizer: [new TerserPlugin()],
},
};
Key Differences
terser-webpack-plugin is specifically designed for webpack integration, offering seamless minification within the webpack build process. It provides webpack-specific optimizations and is easier to set up in webpack projects.
terser, on the other hand, is a more versatile tool that can be used in various JavaScript environments, not limited to webpack. It offers greater flexibility for custom minification tasks but requires more manual setup for webpack integration.
The code comparison illustrates the difference in usage: terser is used programmatically, while terser-webpack-plugin is configured within the webpack configuration file.
JavaScript parser / mangler / compressor / beautifier toolkit
Pros of UglifyJS
- Standalone tool that can be used outside of webpack
- More mature project with a longer history
- Supports older JavaScript versions and legacy code
Cons of UglifyJS
- Slower performance compared to Terser
- Less active development and fewer recent updates
- Limited support for modern JavaScript features
Code Comparison
UglifyJS:
const UglifyJS = require('uglify-js');
const result = UglifyJS.minify(code, {
compress: {
dead_code: true,
drop_debugger: true,
conditionals: true,
evaluate: true
}
});
Terser Webpack Plugin:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [new TerserPlugin({
terserOptions: {
compress: {
dead_code: true,
drop_debugger: true,
conditionals: true,
evaluate: true
}
}
})]
}
};
Both tools offer similar minification options, but Terser Webpack Plugin is specifically designed for integration with webpack, while UglifyJS can be used as a standalone tool. Terser, which powers the webpack plugin, is a fork of UglifyJS and offers improved performance and better support for modern JavaScript features. However, UglifyJS may still be preferred for projects requiring compatibility with older JavaScript versions or for use outside of the webpack ecosystem.
:scissors: An ES6+ aware minifier based on the Babel toolchain (beta)
Pros of Babel Minify
- Integrated with Babel ecosystem, allowing for better compatibility with modern JavaScript features
- Offers more granular control over optimization settings
- Can be used as a standalone tool outside of webpack
Cons of Babel Minify
- Generally slower performance compared to Terser
- Less actively maintained, with fewer recent updates
- May have compatibility issues with some older JavaScript code
Code Comparison
Terser Webpack Plugin configuration:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [new TerserPlugin()],
},
};
Babel Minify Webpack Plugin configuration:
const BabelMinifyPlugin = require('babel-minify-webpack-plugin');
module.exports = {
plugins: [
new BabelMinifyPlugin(),
],
};
Both plugins aim to minify JavaScript code, but they have different approaches and ecosystems. Terser Webpack Plugin is more widely used and generally offers better performance, while Babel Minify provides tighter integration with the Babel ecosystem and more fine-grained control over optimization settings. The choice between the two depends on specific project requirements, performance needs, and compatibility with other tools in the development stack.
A JavaScript checker and optimizer.
Pros of Closure Compiler
- More advanced optimization techniques, potentially resulting in smaller output
- Supports type checking and advanced static analysis
- Can be used as a standalone tool outside of webpack
Cons of Closure Compiler
- Steeper learning curve and more complex configuration
- May require code modifications to work optimally with advanced optimizations
- Slower compilation times compared to Terser
Code Comparison
Terser Webpack Plugin configuration:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [new TerserPlugin()],
},
};
Closure Compiler configuration:
const ClosurePlugin = require('closure-webpack-plugin');
module.exports = {
optimization: {
minimizer: [new ClosurePlugin({ mode: 'STANDARD' })],
},
};
Both plugins aim to minimize JavaScript code, but Closure Compiler offers more advanced optimizations at the cost of increased complexity. Terser is generally easier to set up and use, making it a popular choice for many webpack projects. Closure Compiler may be preferred for larger projects where advanced optimizations and type checking are crucial. The choice between the two depends on project requirements, team expertise, and performance needs.
An extremely fast bundler for the web
Pros of esbuild
- Significantly faster build times due to its Go-based implementation
- Built-in support for various tasks like bundling, minification, and transpilation
- Simpler configuration and API compared to Webpack ecosystem
Cons of esbuild
- Less mature ecosystem and plugin support compared to Webpack
- May not support some advanced optimization techniques available in Terser
- Limited customization options for specific use cases
Code Comparison
terser-webpack-plugin:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [new TerserPlugin()],
},
};
esbuild:
const esbuild = require('esbuild');
esbuild.build({
entryPoints: ['app.js'],
bundle: true,
minify: true,
outfile: 'out.js',
});
The code examples show the basic setup for each tool. terser-webpack-plugin is used as a plugin within Webpack's configuration, while esbuild can be used standalone with a simpler API for bundling and minification.
esbuild offers a more streamlined approach with built-in functionality, whereas terser-webpack-plugin is part of the larger Webpack ecosystem, providing more flexibility but requiring additional configuration.
Rust-based platform for the Web
Pros of swc
- Significantly faster compilation and minification due to Rust implementation
- Broader language support, including TypeScript and JSX
- More actively maintained with frequent updates
Cons of swc
- Less mature and potentially less stable than terser-webpack-plugin
- May have compatibility issues with some webpack configurations
- Steeper learning curve for developers unfamiliar with Rust-based tools
Code Comparison
terser-webpack-plugin:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [new TerserPlugin()],
},
};
swc:
const swc = require('@swc/core');
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'swc-loader',
options: {
jsc: {
minify: {
compress: true,
mangle: true
}
}
}
}
}
]
}
};
The code examples show how to integrate each tool into a webpack configuration. terser-webpack-plugin is added as a minimizer in the optimization section, while swc is configured as a loader with minification options. swc offers more granular control over the minification process but requires more configuration.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
terser-webpack-plugin
This plugin uses terser to minify/minimize your JavaScript.
Getting Started
Webpack v5 comes with the latest terser-webpack-plugin
out of the box. If you are using Webpack v5 or above and wish to customize the options, you will still need to install terser-webpack-plugin
. Using Webpack v4, you have to install terser-webpack-plugin
v4.
To begin, you'll need to install terser-webpack-plugin
:
npm install terser-webpack-plugin --save-dev
or
yarn add -D terser-webpack-plugin
or
pnpm add -D terser-webpack-plugin
Then add the plugin to your webpack
config. For example:
webpack.config.js
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
};
And run webpack
via your preferred method.
Note about source maps
Works only with source-map
, inline-source-map
, hidden-source-map
and nosources-source-map
values for the devtool
option.
Why?
eval
wraps modules ineval("string")
and the minimizer does not handle strings.cheap
has not column information and minimizer generate only a single line, which leave only a single mapping.
Using supported devtool
values enable source map generation.
Options
test
Type:
type test = string | RegExp | Array<string | RegExp>;
Default: /\.m?js(\?.*)?$/i
Test to match files against.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
}),
],
},
};
include
Type:
type include = string | RegExp | Array<string | RegExp>;
Default: undefined
Files to include.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
include: /\/includes/,
}),
],
},
};
exclude
Type:
type exclude = string | RegExp | Array<string | RegExp>;
Default: undefined
Files to exclude.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
exclude: /\/excludes/,
}),
],
},
};
parallel
Type:
type parallel = boolean | number;
Default: true
Use multi-process parallel running to improve the build speed.
Default number of concurrent runs: os.cpus().length - 1
.
Note
Parallelization can speedup your build significantly and is therefore highly recommended.
Warning
If you use Circle CI or any other environment that doesn't provide real available count of CPUs then you need to setup explicitly number of CPUs to avoid
Error: Call retries were exceeded
(see #143, #202).
boolean
Enable/disable multi-process parallel running.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
};
number
Enable multi-process parallel running and set number of concurrent runs.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: 4,
}),
],
},
};
minify
Type:
type minify = (
input: {
[file: string]: string;
},
sourceMap: import("@jridgewell/trace-mapping").SourceMapInput | undefined,
minifyOptions: {
module?: boolean | undefined;
ecma?: import("terser").ECMA | undefined;
},
extractComments:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean)
| {
condition?:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean)
| undefined;
filename?: string | ((fileData: any) => string) | undefined;
banner?:
| string
| boolean
| ((commentsFile: string) => string)
| undefined;
}
| undefined
) => Promise<{
code: string;
map?: import("@jridgewell/trace-mapping").SourceMapInput | undefined;
errors?: (string | Error)[] | undefined;
warnings?: (string | Error)[] | undefined;
extractedComments?: string[] | undefined;
}>;
Default: TerserPlugin.terserMinify
Allows you to override default minify function. By default plugin uses terser package. Useful for using and testing unpublished versions or forks.
Warning
Always use
require
insideminify
function whenparallel
option enabled.
webpack.config.js
// Can be async
const minify = (input, sourceMap, minimizerOptions, extractsComments) => {
// The `minimizerOptions` option contains option from the `terserOptions` option
// You can use `minimizerOptions.myCustomOption`
// Custom logic for extract comments
const { map, code } = require("uglify-module") // Or require('./path/to/uglify-module')
.minify(input, {
/* Your options for minification */
});
return { map, code, warnings: [], errors: [], extractedComments: [] };
};
// Used to regenerate `fullhash`/`chunkhash` between different implementation
// Example: you fix a bug in custom minimizer/custom function, but unfortunately webpack doesn't know about it, so you will get the same fullhash/chunkhash
// to avoid this you can provide version of your custom minimizer
// You don't need if you use only `contenthash`
minify.getMinimizerVersion = () => {
let packageJson;
try {
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
packageJson = require("uglify-module/package.json");
} catch (error) {
// Ignore
}
return packageJson && packageJson.version;
};
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
myCustomOption: true,
},
minify,
}),
],
},
};
terserOptions
Type:
type terserOptions = {
compress?: boolean | CompressOptions;
ecma?: ECMA;
enclose?: boolean | string;
ie8?: boolean;
keep_classnames?: boolean | RegExp;
keep_fnames?: boolean | RegExp;
mangle?: boolean | MangleOptions;
module?: boolean;
nameCache?: object;
format?: FormatOptions;
/** @deprecated */
output?: FormatOptions;
parse?: ParseOptions;
safari10?: boolean;
sourceMap?: boolean | SourceMapOptions;
toplevel?: boolean;
};
Default: default
Terser options.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
ecma: undefined,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
module: false,
// Deprecated
output: null,
format: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false,
},
}),
],
},
};
extractComments
Type:
type extractComments =
| boolean
| string
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean)
| {
condition?:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean)
| undefined;
filename?: string | ((fileData: any) => string) | undefined;
banner?:
| string
| boolean
| ((commentsFile: string) => string)
| undefined;
};
Default: true
Whether comments shall be extracted to a separate file, (see details).
By default extract only comments using /^\**!|@preserve|@license|@cc_on/i
regexp condition and remove remaining comments.
If the original file is named foo.js
, then the comments will be stored to foo.js.LICENSE.txt
.
The terserOptions.format.comments
option specifies whether the comment will be preserved, i.e. it is possible to preserve some comments (e.g. annotations) while extracting others or even preserving comments that have been extracted.
boolean
Enable/disable extracting comments.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
}),
],
},
};
string
Extract all
or some
(use /^\**!|@preserve|@license|@cc_on/i
RegExp) comments.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: "all",
}),
],
},
};
RegExp
All comments that match the given expression will be extracted to the separate file.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: /@extract/i,
}),
],
},
};
function
All comments that match the given expression will be extracted to the separate file.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: (astNode, comment) => {
if (/@extract/i.test(comment.value)) {
return true;
}
return false;
},
}),
],
},
};
object
Allow to customize condition for extract comments, specify extracted file name and banner.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
condition
Type:
type condition =
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean)
| undefined;
Condition what comments you need extract.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: "some",
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
filename
Type:
type filename = string | ((fileData: any) => string) | undefined;
Default: [file].LICENSE.txt[query]
Available placeholders: [file]
, [query]
and [filebase]
([base]
for webpack 5).
The file where the extracted comments will be stored.
Default is to append the suffix .LICENSE.txt
to the original filename.
Warning
We highly recommend using the
txt
extension. Usingjs
/cjs
/mjs
extensions may conflict with existing assets which leads to broken code.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: "extracted-comments.js",
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
banner
Type:
type banner = string | boolean | ((commentsFile: string) => string) | undefined;
Default: /*! For license information please see ${commentsFile} */
The banner text that points to the extracted file and will be added on top of the original file.
Can be false
(no banner), a String
, or a Function<(string) -> String>
that will be called with the filename where extracted comments have been stored.
Will be wrapped into comment.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: true,
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (commentsFile) => {
return `My custom banner about license information ${commentsFile}`;
},
},
}),
],
},
};
Examples
Preserve Comments
Extract all legal comments (i.e. /^\**!|@preserve|@license|@cc_on/i
) and preserve /@license/i
comments.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: /@license/i,
},
},
extractComments: true,
}),
],
},
};
Remove Comments
If you avoid building with comments, use this config:
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: false,
},
},
extractComments: false,
}),
],
},
};
uglify-js
UglifyJS
is a JavaScript parser, minifier, compressor and beautifier toolkit.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.uglifyJsMinify,
// `terserOptions` options will be passed to `uglify-js`
// Link to options - https://github.com/mishoo/UglifyJS#minify-options
terserOptions: {},
}),
],
},
};
swc
swc
is a super-fast compiler written in rust; producing widely-supported javascript from modern standards and typescript.
Warning
the
extractComments
option is not supported and all comments will be removed by default, it will be fixed in future
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.swcMinify,
// `terserOptions` options will be passed to `swc` (`@swc/core`)
// Link to options - https://swc.rs/docs/config-js-minify
terserOptions: {},
}),
],
},
};
esbuild
esbuild
is an extremely fast JavaScript bundler and minifier.
Warning
the
extractComments
option is not supported and all legal comments (i.e. copyright, licenses and etc) will be preserved
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.esbuildMinify,
// `terserOptions` options will be passed to `esbuild`
// Link to options - https://esbuild.github.io/api/#minify
// Note: the `minify` options is true by default (and override other `minify*` options), so if you want to disable the `minifyIdentifiers` option (or other `minify*` options) please use:
// terserOptions: {
// minify: false,
// minifyWhitespace: true,
// minifyIdentifiers: false,
// minifySyntax: true,
// },
terserOptions: {},
}),
],
},
};
Custom Minify Function
Override default minify function - use uglify-js
for minification.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: (file, sourceMap) => {
// https://github.com/mishoo/UglifyJS2#minify-options
const uglifyJsOptions = {
/* your `uglify-js` package options */
};
if (sourceMap) {
uglifyJsOptions.sourceMap = {
content: sourceMap,
};
}
return require("uglify-js").minify(file, uglifyJsOptions);
},
}),
],
},
};
Typescript
With default terser minify function:
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: true,
},
}),
],
},
};
With built-in minify functions:
import type { JsMinifyOptions as SwcOptions } from "@swc/core";
import type { MinifyOptions as UglifyJSOptions } from "uglify-js";
import type { TransformOptions as EsbuildOptions } from "esbuild";
import type { MinifyOptions as TerserOptions } from "terser";
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin<SwcOptions>({
minify: TerserPlugin.swcMinify,
terserOptions: {
// `swc` options
},
}),
new TerserPlugin<UglifyJSOptions>({
minify: TerserPlugin.uglifyJsMinify,
terserOptions: {
// `uglif-js` options
},
}),
new TerserPlugin<EsbuildOptions>({
minify: TerserPlugin.esbuildMinify,
terserOptions: {
// `esbuild` options
},
}),
// Alternative usage:
new TerserPlugin<TerserOptions>({
minify: TerserPlugin.terserMinify,
terserOptions: {
// `terser` options
},
}),
],
},
};
Contributing
Please take a moment to read our contributing guidelines if you haven't yet done so.
License
Top Related Projects
🗜 JavaScript parser, mangler and compressor toolkit for ES6+
JavaScript parser / mangler / compressor / beautifier toolkit
:scissors: An ES6+ aware minifier based on the Babel toolchain (beta)
A JavaScript checker and optimizer.
An extremely fast bundler for the web
Rust-based platform for the Web
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot