Spec-Zone.ru › webpack 5

TerserWebpackPlugin

Предупреждение: TerserWebpackPlugin — это пакет стороннего разработчика, поддерживаемый участниками сообщества. Возможно, он не имеет такой же поддержки, политики безопасности или лицензии, как webpack, и не поддерживается webpack.

Этот плагин использует 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
  • include
  • exclude
  • parallel
  • minify
  • terserOptions
  • extractComments

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
        },
      }),
    ],
  },
};

Содействие

Пожалуйста, потратьте некоторое время, чтобы ознакомиться с нашими рекомендациями по участию в разработке, если вы этого еще не сделали.

CONTRIBUTING

Лицензия

MIT

© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/plugins/terser-webpack-plugin

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API