此外掛使用 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
。
僅適用於 devtool
選項的 source-map
、inline-source-map
、hidden-source-map
和 nosources-source-map
值。
原因:
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 或任何其他無法提供實際可用 CPU 數量的環境,則需要明確設定 CPU 數量,以避免出現
Error: Call retries were exceeded
(請參閱 #143、#202)。
布林值
啟用/停用多處理程序並行執行。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
};
數字
啟用多處理程序並行執行,並設定並行執行的數量。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: 4,
}),
],
},
};
最小化
類型
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 套件。這對於使用和測試未發布的版本或分支很有用。
警告
當啟用
parallel
選項時,請務必在minify
函式內使用require
.
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
選項指定是否保留註解,亦即有可能在萃取其他註解或甚至保留已萃取的註解時,保留某些註解(例如註釋)。
布林值
啟用/停用萃取註解。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
}),
],
},
};
字串
擷取全部
或部分
(使用 /^\**!|@preserve|@license|@cc_on/i
RegExp)註解。
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]
(Webpack 5 為 [base]
)。
將擷取的註解儲存到的檔案。預設值是將字尾 .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;
預設值:/*! 如需授權資訊,請參閱 ${commentsFile} */
指向提取檔案的橫幅文字,且會新增在原始檔案的頂端。可以是 false
(無橫幅)、字串
或 Function<(字串) -> 字串>
,後者會以儲存提取註解之檔案名稱為參數呼叫。會包裝成註解。
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 編寫的超快速編譯器;從現代標準和 TypeScript 產生廣泛支援的 JavaScript。
警告
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.dev.org.tw/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.dev.org.tw/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);
},
}),
],
},
};
使用預設的 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
},
}),
],
},
};
如果您尚未閱讀我們的貢獻指南,請花點時間閱讀。