TerserWebpackPlugin
Этот плагин использует terser для минификации JavaScript.
Начало работы
Webpack v5 поставляется с последней terser-webpack-plugin по умолчанию. Если вы используете Webpack v5 или выше и хотите настроить параметры, вам всё равно нужно установить terser-webpack-plugin. При использовании Webpack v4, необходимо установить terser-webpack-plugin v4.
Для начала вам нужно установить terser-webpack-plugin:
npm install terser-webpack-plugin --save-dev
или
yarn add -D terser-webpack-plugin
или
pnpm add -D terser-webpack-plugin
Затем добавьте плагин в вашу webpack конфигурацию. Например:
webpack.config.js
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
}; И запустите webpack через выбранный вами метод.
Примечание о картах исходного кода
Работает только со значениями source-map, inline-source-map, hidden-source-map и nosources-source-map для параметра devtool.
Почему?
-
evalоборачивает модули вeval("string")и минификатор не обрабатывает строки. -
cheapне содержит информации о колонках, а минификатор генерирует только одну строку, что оставляет только одно сопоставление.
Использование поддерживаемых значений devtool позволяет сгенерировать карты исходного кода.
Параметры
test
Тип:
type test = string | RegExp | Array<string | RegExp>;
По умолчанию: /\.m?js(\?.*)?$/i
Тест для сопоставления файлов.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
}),
],
},
};
include
Тип:
type include = string | RegExp | Array<string | RegExp>;
По умолчанию: undefined
Файлы для включения.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
include: /\/includes/,
}),
],
},
};
exclude
Тип:
type exclude = string | RegExp | Array<string | RegExp>;
По умолчанию: undefined
Файлы для исключения.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
exclude: /\/excludes/,
}),
],
},
};
parallel
Тип:
type parallel = boolean | number;
По умолчанию: true
Использовать многопроцессорную параллельную обработку для ускорения сборки. По умолчанию количество одновременных запусков: os.cpus().length - 1.
Примечание
Параллелизация может значительно ускорить сборку и поэтому настоятельно рекомендуется.
Предупреждение
Если вы используете Circle CI или любую другую среду, которая не предоставляет реальное количество ЦП, вам необходимо явно установить количество ЦП, чтобы избежать
Error: Call retries were exceeded(см. #143, #202).
boolean
Включить/отключить многопроцессорную параллельную обработку.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
};
number
Включить многопроцессорную параллельную обработку и задать количество одновременных запусков.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: 4,
}),
],
},
};
minify
Тип:
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;
}>; По умолчанию: TerserPlugin.terserMinify
Позволяет переопределить функцию минификации по умолчанию. По умолчанию плагин использует пакет terser. Полезно для использования и тестирования неопубликованных версий или форков.
Предупреждение
Всегда используйте
requireвнутри функцииminify, когда параметрparallelвключен.
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 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;
}; По умолчанию: по умолчанию
Параметры terser.
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 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;
}; По умолчанию: true
Выводить ли комментарии в отдельный файл (см. подробности). По умолчанию извлекаются только комментарии, использующие условие регулярного выражения /^\**!|@preserve|@license|@cc_on/i, и удаляются оставшиеся комментарии. Если исходный файл называется foo.js, то комментарии будут сохранены в foo.js.LICENSE.txt. Параметр terserOptions.format.comments указывает, сохранять ли комментарий, т. е. можно сохранить некоторые комментарии (например, аннотации), извлекая другие или даже сохраняя извлечённые комментарии.
boolean
Включить/отключить извлечение комментариев.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
}),
],
},
};
string
Извлечь all или some (используйте регулярное выражение /^\**!|@preserve|@license|@cc_on/i) комментарии.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: "all",
}),
],
},
};
RegExp
Все комментарии, которые соответствуют данному выражению, будут извлечены в отдельный файл.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: /@extract/i,
}),
],
},
};
function
Все комментарии, которые соответствуют данному выражению, будут извлечены в отдельный файл.
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
Позволяет настроить условие для извлечения комментариев, указать имя извлечённого файла и баннер.
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 condition =
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean)
| undefined; Условие, какие комментарии нужно извлечь.
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 filename = string | ((fileData: any) => string) | undefined;
По умолчанию: [file].LICENSE.txt[query]
Доступные плейсхолдеры: [file], [query] и [filebase] ([base] для webpack 5).
Файл, в котором будут сохранены извлечённые комментарии. По умолчанию добавляется суффикс .LICENSE.txt к имени исходного файла.
Предупреждение
Мы настоятельно рекомендуем использовать расширение
txt. Использование расширенийjs/cjs/mjsможет конфликтовать с существующими ресурсами, что приводит к ошибкам в коде.
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 banner = string | boolean | ((commentsFile: string) => string) | undefined;
По умолчанию: /*! For license information please see ${commentsFile} */
Текст баннера, указывающий на извлечённый файл и добавляемый в начало исходного файла. Может быть false (без баннера), строкой, или функцией, которая будет вызвана с именем файла, в котором сохранены извлеченные комментарии. Будет обернута в комментарий.
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}`;
},
},
}),
],
},
}; Примеры
Сохранение комментариев
Извлечь все легальные комментарии (т.е. /^\**!|@preserve|@license|@cc_on/i) и сохранить /@license/i комментарии.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: /@license/i,
},
},
extractComments: true,
}),
],
},
}; Удаление комментариев
Если вы хотите избежать комментариев при сборке, используйте эту конфигурацию:
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: false,
},
},
extractComments: false,
}),
],
},
};
uglify-js
UglifyJS — это набор инструментов для парсинга, минификации, сжатия и форматирования JavaScript.
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 — это сверхбыстрый компилятор, написанный на Rust, который генерирует широко поддерживаемый JavaScript из современных стандартов и TypeScript.
Предупреждение
Параметр
extractCommentsне поддерживается, и все комментарии по умолчанию будут удалены. Будет исправлено в будущем.
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 — это чрезвычайно быстрый JavaScript-бандлер и минификатор.
Предупреждение
Параметр
extractCommentsне поддерживается, и все легальные комментарии (например, авторские права, лицензии и т.д.) будут сохранены.
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: {},
}),
],
},
}; Пользовательская функция минификации
Переопределить функцию минификации по умолчанию — используйте uglify-js для минификации.
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
С функцией минификации по умолчанию terser:
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: true,
},
}),
],
},
}; С встроенными функциями минификации:
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
},
}),
],
},
}; Содействие
Пожалуйста, потратьте некоторое время, чтобы ознакомиться с нашими рекомендациями по участию в разработке, если вы этого еще не сделали.
Лицензия
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/plugins/terser-webpack-plugin