{String\|RegExp\|Array<String\|RegExp>}
The AutomaticPrefetchPlugin discovers all modules from the previous compilation upfront while watching for changes, trying to improve the incremental build times. Compared to PrefetchPlugin which discovers a single module upfront.
May or may not have a performance benefit since the incremental build times are pretty fast.
webpack.config.js
module.exports = {
// ...
plugins: [
new webpack.AutomaticPrefetchPlugin()
]
}; Adds a banner to the top of each generated chunk.
const webpack = require('webpack');
new webpack.BannerPlugin(banner);
// or
new webpack.BannerPlugin(options); {
banner: string | function, // the banner as string or function, it will be wrapped in a comment
raw: boolean, // if true, banner will not be wrapped in a comment
entryOnly: boolean, // if true, the banner will only be added to the entry chunks
test: string | RegExp | [string, RegExp], // Include all modules that pass test assertion.
include: string | RegExp | [string, RegExp], // Include all modules matching any of these conditions.
exclude: string | RegExp | [string, RegExp], // Exclude all modules matching any of these conditions.
} import webpack from 'webpack';
// string
new webpack.BannerPlugin({
banner: 'hello world'
});
// function
new webpack.BannerPlugin({
banner: (yourVariable) => { return `yourVariable: ${yourVariable}`; }
}); Since webpack 2.5.0, placeholders are evaluated in the banner string:
import webpack from 'webpack';
new webpack.BannerPlugin({
banner: 'fullhash:[fullhash], chunkhash:[chunkhash], name:[name], filebase:[filebase], query:[query], file:[file]'
}); This plugin supports the use of Google's Closure Tools with webpack.
Note: This is the webpack 4 branch.
Closure-Compiler is a full optimizing compiler and transpiler. It offers unmatched optimizations, provides type checking and can easily target transpilation to different versions of ECMASCRIPT.
Closure-Library is a utility library designed for full compatibility with Closure-Compiler.
For webpack 3 support, see https://github.com/webpack-contrib/closure-webpack-plugin/tree/webpack-3
You must install both the google-closure-compiler package as well as the closure-webpack-plugin.
npm install --save-dev closure-webpack-plugin google-closure-compiler
const ClosurePlugin = require('closure-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new ClosurePlugin({mode: 'STANDARD'}, {
// compiler flags here
//
// for debugging help, try these:
//
// formatting: 'PRETTY_PRINT'
// debug: true,
// renaming: false
})
]
}
}; native, java or javascript. Controls which version to use of closure-compiler. By default the plugin will attempt to automatically choose the fastest option available. JAVASCRIPT does not require the JVM to be installed. Not all flags are supported. JAVA utilizes the jvm. Utilizes multiple threads for parsing and results in faster compilation for large builds.NATIVE only available on linux or MacOS. Faster compilation times without requiring a JVM.STANDARD (default) or AGGRESSIVE_BUNDLE. Controls how the plugin utilizes the compiler. STANDARD mode, closure-compiler is used as a direct replacement for other minifiers as well as most Babel transformations. AGGRESSIVE_BUNDLE mode, the compiler performs additional optimizations of modules to produce a much smaller filefalse. In order to decrease build times, this plugin by default only operates on the main compilation. Plugins such as extract-text-plugin and html-webpack-plugin run as child compilations and usually do not need transpilation or minification. You can enable this for all child compilations by setting this option to true. For specific control, the option can be set to a function which will be passed a compilation object.function(compilation) { return /html-webpack/.test(compilation.name); }.filename or chunkfilename properties. Used to override the output file naming for a particular compilation. See https://webpack.js.org/configuration/output/ for details.The plugin controls several compiler flags. The following flags should not be used in any mode:
In this mode, the compiler rewrites CommonJS modules and hoists require calls. Some modules are not compatible with this type of rewriting. In particular, hoisting will cause the following code to execute out of order:
const foo = require('foo');
addPolyfillToFoo(foo);
const bar = require('bar'); Aggressive Bundle Mode utilizes a custom runtime in which modules within a chunk file are all included in the same scope. This avoids the cost of small modules.
In Aggressive Bundle Mode, a file can only appear in a single output chunk. Use the Split Chunks Plugin to split duplicated files into a single output chunk. If a module is utilized by more than one chunk, the plugin will move it up to the first common parent to prevent code duplication.
The concatenatedModules optimization is not compatible with this mode since Closure-Compiler performs an equivalent optimization). The plugin will emit a warning if this optimization is not disabled.
You can add the plugin multiple times. This easily allows you to target multiple output languages. Use ECMASCRIPT_2015 for modern browsers and ECMASCRIPT5 for older browsers.
Use the output option to change the filenames of specific plugin instances.
Use <script type="module" src="es6_out_path.js"> to target modern browsers and <script nomodule src="es5_out_path.js"> for older browsers.
See the es5 and es6 output demo for an example.
In order for webpack to recognize goog.require, goog.provide, goog.module and related primitives, a separate plugin is shipped.
const ClosurePlugin = require('closure-webpack-plugin');
module.exports = {
plugins: [
new ClosurePlugin.LibraryPlugin({
closureLibraryBase: require.resolve(
'google-closure-library/closure/goog/base'
),
deps: [
require.resolve('google-closure-library/closure/goog/deps'),
'./public/deps.js',
],
})
]
}; The plugin adds extra functionality to support using Closure Library without Closure Compiler. This is typically used during development mode. When the webpack mode is production, only dependency information is provided to webpack as Closure Compiler will natively recognize the Closure Library primitives.
The Closure Library Plugin is only compatible with the AGGRESSIVE_BUNDLE mode of the Closure-Compiler webpack plugin.
| Chad Killingsworth | Joshua Wiens |
The CommonsChunkPlugin is an opt-in feature that creates a separate file (known as a chunk), consisting of common modules shared between multiple entry points.
The CommonsChunkPlugin has been removed in webpack v4 legato. To learn how chunks are treated in the latest version, check out the SplitChunksPlugin.
By separating common modules from bundles, the resulting chunked file can be loaded once initially, and stored in cache for later use. This results in page speed optimizations as the browser can quickly serve the shared code from cache, rather than being forced to load a larger bundle whenever a new page is visited.
new webpack.optimize.CommonsChunkPlugin(options); {
name: string, // or
names: string[],
// The chunk name of the commons chunk. An existing chunk can be selected by passing a name of an existing chunk.
// If an array of strings is passed this is equal to invoking the plugin multiple times for each chunk name.
// If omitted and `options.async` or `options.children` is set all chunks are used, otherwise `options.filename`
// is used as chunk name.
// When using `options.async` to create common chunks from other async chunks you must specify an entry-point
// chunk name here instead of omitting the `option.name`.
filename: string,
// The filename template for the commons chunk. Can contain the same placeholders as `output.filename`.
// If omitted the original filename is not modified (usually `output.filename` or `output.chunkFilename`).
// This option is not permitted if you're using `options.async` as well, see below for more details.
minChunks: number|Infinity|function(module, count) => boolean,
// The minimum number of chunks which need to contain a module before it's moved into the commons chunk.
// The number must be greater than or equal 2 and lower than or equal to the number of chunks.
// Passing `Infinity` just creates the commons chunk, but moves no modules into it.
// By providing a `function` you can add custom logic. (Defaults to the number of chunks)
chunks: string[],
// Select the source chunks by chunk names. The chunk must be a child of the commons chunk.
// If omitted all entry chunks are selected.
children: boolean,
// If `true` all children of the commons chunk are selected
deepChildren: boolean,
// If `true` all descendants of the commons chunk are selected
async: boolean|string,
// If `true` a new async commons chunk is created as child of `options.name` and sibling of `options.chunks`.
// It is loaded in parallel with `options.chunks`.
// Instead of using `option.filename`, it is possible to change the name of the output file by providing
// the desired string here instead of `true`.
minSize: number,
// Minimum size of all common module before a commons chunk is created.
} Generate an extra chunk, which contains common modules shared between entry points.
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
// (the commons chunk name)
filename: 'commons.js',
// (the filename of the commons chunk)
// minChunks: 3,
// (Modules must be shared between 3 entries)
// chunks: ["pageA", "pageB"],
// (Only use these entries)
}); You must load the generated chunk before the entry point:
<script src="commons.js" charset="utf-8"></script>
<script src="entry.bundle.js" charset="utf-8"></script> Split your code into vendor and application.
module.exports = {
//...
entry: {
vendor: ['jquery', 'other-lib'],
app: './entry'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
// filename: "vendor.js"
// (Give the chunk a different name)
minChunks: Infinity,
// (with more entries, this ensures that no other module
// goes into the vendor chunk)
})
]
}; <script src="vendor.js" charset="utf-8"></script>
<script src="app.js" charset="utf-8"></script> In combination with long term caching you may need to use the
ChunkManifestWebpackPluginto avoid the vendor chunk changes. You should also use records to ensure stable module ids, e.g. usingNamedModulesPluginorHashedModuleIdsPlugin.
With Code Splitting, multiple child chunks of an entry chunk can have common dependencies. To prevent duplication these can be moved into the parent. This reduces overall size, but does have a negative effect on the initial load time. If it is expected that users will need to download many sibling chunks, i.e. children of the entry chunk, then this should improve load time overall.
new webpack.optimize.CommonsChunkPlugin({
// names: ["app", "subPageA"]
// (choose the chunks, or omit for all chunks)
children: true,
// (select all children of chosen chunks)
// minChunks: 3,
// (3 children must share the module before it's moved)
}); Similar to the above one, but instead of moving common modules into the parent (which increases initial load time) a new async-loaded additional commons chunk is used. This is automatically downloaded in parallel when the additional chunk is downloaded.
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
// or
names: ['app', 'subPageA'],
// the name or list of names must match the name or names
// of the entry points that create the async chunks
children: true,
// (use all children of the chunk)
async: true,
// (create an async commons chunk)
minChunks: 3,
// (3 children must share the module before it's separated)
}); minChunks property a functionYou also have the ability to pass the minChunks property a function. This function is called by the CommonsChunkPlugin and calls the function with module and count arguments.
The module argument represents each module in the chunks you have provided via the name/names property. module has the shape of a NormalModule, which has two particularly useful properties for this use case:
module.context: The directory that stores the file. For example: '/my_project/node_modules/example-dependency'module.resource: The name of the file being processed. For example: '/my_project/node_modules/example-dependency/index.js'The count argument represents how many chunks the module is used in.
This option is useful when you want to have fine-grained control over how the CommonsChunk algorithm determines where modules should be moved to.
new webpack.optimize.CommonsChunkPlugin({
name: 'my-single-lib-chunk',
filename: 'my-single-lib-chunk.js',
minChunks: function(module, count) {
// If module has a path, and inside of the path exists the name "somelib",
// and it is used in 3 separate chunks/entries, then break it out into
// a separate chunk with chunk keyname "my-single-lib-chunk", and filename "my-single-lib-chunk.js"
return module.resource && (/somelib/).test(module.resource) && count === 3;
}
}); As seen above, this example allows you to move only one lib to a separate file if and only if all conditions are met inside the function.
This concept may be used to obtain implicit common vendor chunks:
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
// this assumes your vendor imports exist in the node_modules directory
return module.context && module.context.includes('node_modules');
}
}); To extract the webpack bootstrap logic into a separate file, use the CommonsChunkPlugin on a name which is not defined as entry. Commonly the name manifest is used. See the caching guide for details.
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}); Since the vendor and manifest chunk use a different definition for minChunks, you need to invoke the plugin twice:
[
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function(module){
return module.context && module.context.includes('node_modules');
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
]; Prepare compressed versions of assets to serve them with Content-Encoding.
To begin, you'll need to install compression-webpack-plugin:
$ npm install compression-webpack-plugin --save-dev
Then add the plugin to your webpack config. For example:
webpack.config.js
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
plugins: [new CompressionPlugin()],
}; And run webpack via your preferred method.
| Name | Type | Default | Description |
|---|---|---|---|
Name Type Default Description
| {String\|RegExp\|Array<String\|RegExp>} | undefined | Include all assets that pass test assertion |
Name Type Default Description
| {String\|RegExp\|Array<String\|RegExp>} | undefined | Include all assets matching any of these conditions |
Name Type Default Description
| {String\|RegExp\|Array<String\|RegExp>} | undefined | Exclude all assets matching any of these conditions |
Name Type Default Description
| {String\|Function} | gzip | The compression algorithm/function |
Name Type Default Description
| {Object} | maximum available compression level, for gzip: { level: 9 } | Compression options for algorithm |
Name Type Default Description
| {Number} | 0 | Only assets bigger than this size are processed (in bytes) |
Name Type Default Description
| {Number} | 0.8 | Only assets that compress better than this ratio are processed (minRatio = Compressed Size / Original Size) |
Name Type Default Description
| {String\|Function} | [path][base].gz | The target asset filename |
Name Type Default Description
| {Boolean} | false | Whether to delete the original assets or not |
Name Type Default Description
| {Boolean} | true | Enable file caching |
testType: String|RegExp|Array<String|RegExp> Default: undefined
Include all assets that pass test assertion.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
test: /\.js(\?.*)?$/i,
}),
],
}; includeType: String|RegExp|Array<String|RegExp> Default: undefined
Include all assets matching any of these conditions.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
include: /\/includes/,
}),
],
}; excludeType: String|RegExp|Array<String|RegExp> Default: undefined
Exclude all assets matching any of these conditions.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
exclude: /\/excludes/,
}),
],
}; algorithmType: String|Function Default: gzip
The compression algorithm/function.
ℹ️ If you use custom function for the
algorithmoption, the default value of thecompressionOptionsoption is{}.
StringThe algorithm is taken from zlib.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
algorithm: 'gzip',
}),
],
}; FunctionAllow to specify a custom compression function.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
algorithm(input, compressionOptions, callback) {
return compressionFunction(input, compressionOptions, callback);
},
}),
],
}; compressionOptionsType: Object Default: { level: 9 }
Compression options for algorithm.
You can find all options here zlib.
ℹ️ If you use custom function for the
algorithmoption, the default value is{}.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
compressionOptions: { level: 1 },
}),
],
}; thresholdType: Number Default: 0
Only assets bigger than this size are processed. In bytes.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
threshold: 8192,
}),
],
}; minRatioType: Number Default: 0.8
Only assets that compress better than this ratio are processed (minRatio = Compressed Size / Original Size). Example: you have image.png file with 1024b size, compressed version of file has 768b size, so minRatio equal 0.75. In other words assets will be processed when the Compressed Size / Original Size value less minRatio value.
You can use 1 value to process assets that are smaller than the original.
Use a value of Infinity to process all assets even if they are larger than the original size or their original size is 0 bytes (useful when you are pre-zipping all assets for AWS).
Use a value of Number.MAX_SAFE_INTEGER to process all assets even if they are larger than the original size, excluding assets with their original size is 0 bytes.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
// Compress all assets, including files with `0` bytes size
// minRatio: Infinity
// Compress all assets, excluding files with `0` bytes size
// minRatio: Number.MAX_SAFE_INTEGER
minRatio: 0.8,
}),
],
}; filenameType: String|Function Default: "[path][base].gz"
The target asset filename.
StringFor example we have assets/images/image.png?foo=bar#hash:
[path] is replaced with the directories to the original asset, included trailing / (assets/images/).
[file] is replaced with the path of original asset (assets/images/image.png).
[base] is replaced with the base ([name] + [ext]) of the original asset (image.png).
[name] is replaced with the name of the original asset (image).
[ext] is replaced with the extension of the original asset, included . (.png).
[query] is replaced with the query of the original asset, included ? (?foo=bar).
[fragment] is replaced with the fragment (in the concept of URL it is called hash) of the original asset (#hash).
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
filename: '[path][base].gz',
}),
],
}; Functionwebpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
filename(pathData) {
// The `pathData` argument contains all placeholders - `path`/`name`/`ext`/etc
// Available properties described above, for the `String` notation
if (/\.svg$/.test(pathData.file)) {
return 'assets/svg/[path][base].gz';
}
return 'assets/js/[path][base].gz';
},
}),
],
}; deleteOriginalAssetsType: Boolean Default: false
Whether to delete the original assets or not.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
deleteOriginalAssets: true,
}),
],
}; cache⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache.
Type: Boolean|String Default: true
Enable file caching. The default path to cache directory: node_modules/.cache/compression-webpack-plugin.
BooleanEnable/disable file caching.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
cache: true,
}),
],
}; StringEnable file caching and set path to cache directory.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
cache: 'path/to/cache',
}),
],
}; Prepare compressed versions of assets using zopfli library.
ℹ️
@gfx/zopflirequire minimum8version ofnode.
To begin, you'll need to install @gfx/zopfli:
$ npm install @gfx/zopfli --save-dev
webpack.config.js
const zopfli = require('@gfx/zopfli');
module.exports = {
plugins: [
new CompressionPlugin({
compressionOptions: {
numiterations: 15,
},
algorithm(input, compressionOptions, callback) {
return zopfli.gzip(input, compressionOptions, callback);
},
}),
],
}; Brotli is a compression algorithm originally developed by Google, and offers compression superior to gzip.
Node 10.16.0 and later has native support for Brotli compression in its zlib module.
We can take advantage of this built-in support for Brotli in Node 10.16.0 and later by just passing in the appropriate algorithm to the CompressionPlugin:
webpack.config.js
const zlib = require('zlib');
module.exports = {
plugins: [
new CompressionPlugin({
filename: '[path][base].br',
algorithm: 'brotliCompress',
test: /\.(js|css|html|svg)$/,
compressionOptions: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: https://github.com/webpack-contrib/compression-webpack-plugin/blob/master/11,
},
},
threshold: 10240,
minRatio: 0.8,
deleteOriginalAssets: false,
}),
],
}; Note Brotli’s BROTLI_PARAM_QUALITY option is functionally equivalent to zlib’s level option. You can find all Brotli’s options in the relevant part of the zlib module documentation.
webpack.config.js
const zlib = require('zlib');
module.exports = {
plugins: [
new CompressionPlugin({
filename: '[path][base].gz',
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8,
}),
new CompressionPlugin({
filename: '[path][base].br',
algorithm: 'brotliCompress',
test: /\.(js|css|html|svg)$/,
compressionOptions: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: https://github.com/webpack-contrib/compression-webpack-plugin/blob/master/11,
},
},
threshold: 10240,
minRatio: 0.8,
}),
],
}; Please take a moment to read our contributing guidelines if you haven't yet done so.
Context refers to a require with an expression such as require('./locale/' + name + '.json').
The ContextExclusionPlugin allows you to exclude context. Provide RegExp as an argument when initializing the Plugin to exclude all context that matches it.
webpack.config.js
module.exports = {
plugins: [
new webpack.ContextExclusionPlugin(/dont/)
]
}; Context refers to a require with an expression such as require('./locale/' + name + '.json'). When encountering such an expression, webpack infers the directory ('./locale/') and a regular expression (/^.*\.json$/). Since the name is not known at compile time, webpack includes every file as module in the bundle.
The ContextReplacementPlugin allows you to override the inferred information. There are various ways to configure the plugin:
new webpack.ContextReplacementPlugin(
resourceRegExp: RegExp,
newContentResource?: string,
newContentRecursive?: boolean,
newContentRegExp?: RegExp
) If the resource (directory) matches resourceRegExp, the plugin replaces the default resource, recursive flag or generated regular expression with newContentResource, newContentRecursive or newContextRegExp respectively. If newContentResource is relative, it is resolved relative to the previous resource.
Here's a small example to restrict module usage:
new webpack.ContextReplacementPlugin(
/moment[/\\]locale$/,
/de|fr|hu/
); The moment/locale context is restricted to files matching /de|fr|hu/. Thus only those locales are included (see this issue for more information).
new webpack.ContextReplacementPlugin(
resourceRegExp: RegExp,
newContentCallback: (data) => void
); The newContentCallback function is given a data object of the ContextModuleFactory and is expected to overwrite the request attribute of the supplied object.
Using this callback we can dynamically redirect requests to a new location:
new webpack.ContextReplacementPlugin(/^\.\/locale$/, (context) => {
if ( !/\/moment\//.test(context.context) ) return;
Object.assign(context, {
regExp: /^\.\/\w+/,
request: '../../locale' // resolved relatively
});
}); The newContentResource and newContentCreateContextMap parameters are also available:
new webpack.ContextReplacementPlugin(
resourceRegExp: RegExp,
newContentResource: string,
newContentCreateContextMap: object // mapping runtime-request (userRequest) to compile-time-request (request)
); These two parameters can be used together to redirect requests in a more targeted way. The newContentCreateContextMap allows you to map runtime requests to compile requests in the form of an object:
new ContextReplacementPlugin(/selector/, './folder', {
'./request': './request',
'./other-request': './new-request'
}); Copies individual files or entire directories, which already exist, to the build directory.
To begin, you'll need to install copy-webpack-plugin:
$ npm install copy-webpack-plugin --save-dev
Then add the plugin to your webpack config. For example:
webpack.config.js
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: 'source', to: 'dest' },
{ from: 'other', to: 'public' },
],
}),
],
}; ℹ️
webpack-copy-pluginis not designed to copy files generated from the build process; rather, it is to copy files that already exist in the source tree, as part of the build process.
ℹ️ If you want
webpack-dev-serverto write files to the output directory during development, you can force it with thewriteToDiskoption or thewrite-file-webpack-plugin.
ℹ️ You can get the original source filename from Asset Objects.
The plugin's signature:
webpack.config.js
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: 'source', to: 'dest' },
{ from: 'other', to: 'public' },
],
options: {
concurrency: 100,
},
}),
],
}; | Name | Type | Default | Description |
|---|---|---|---|
Name Type Default Description
| {String} | undefined | Glob or path from where we сopy files. |
Name Type Default Description
| {String} | compiler.options.output | Output path. |
Name Type Default Description
| {String} | options.context \|\| compiler.options.context | A path that determines how to interpret the from path. |
Name Type Default Description
| {Object} | undefined | Options passed to the glob pattern matching library including ignore option. |
Name Type Default Description
| {Function} | undefined | Allows to filter copied assets. |
Name Type Default Description
| {String} | undefined | Determinate what is to option - directory, file or template. |
Name Type Default Description
| {Boolean} | false | Overwrites files already in compilation.assets (usually added by other plugins/loaders). |
Name Type Default Description
| {Boolean} | false | Removes all directory references and only copies file names. |
Name Type Default Description
| {Function} | undefined | Allows to modify the file contents. |
Name Type Default Description
| {Boolean\|String\|Object} | false | Enable transform caching. You can use { cache: { key: 'my-cache-key' } } to invalidate the cache. |
Name Type Default Description
| {Function} | undefined | Allows to modify the writing path. |
Name Type Default Description
| {Boolean} | false | Doesn't generate an error on missing file(s). |
fromType: String Default: undefined
Glob or path from where we сopy files. Globs accept fast-glob pattern-syntax. Glob can only be a string.
⚠️ Don't use directly
\\infromoption if it is aglob(i.epath\to\file.ext) option because on UNIX the backslash is a valid character inside a path component, i.e., it's not a separator. On Windows, the forward slash and the backward slash are both separators. Instead please use/.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
'relative/path/to/file.ext',
'relative/path/to/dir',
path.resolve(__dirname, 'src', 'file.ext'),
path.resolve(__dirname, 'src', 'dir'),
'**/*',
{
from: '**/*',
},
// If absolute path is a `glob` we replace backslashes with forward slashes, because only forward slashes can be used in the `glob`
path.posix.join(
path.resolve(__dirname, 'src').replace(/\\/g, '/'),
'*.txt'
),
],
}),
],
}; For windowsIf you define from as absolute file path or absolute folder path on Windows, you can use windows path segment (\\)
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, 'file.txt'),
},
],
}),
],
}; But you should always use forward-slashes in glob expressions See fast-glob manual.
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
// If absolute path is a `glob` we replace backslashes with forward slashes, because only forward slashes can be used in the `glob`
from: path.posix.join(
path.resolve(__dirname, 'fixtures').replace(/\\/g, '/'),
'*.txt'
),
},
],
}),
],
}; The context behaves differently depending on what the from is (glob, file or dir). More examples
toType: String Default: compiler.options.output
Output path.
⚠️ Don't use directly
\\into(i.epath\to\dest) option because on UNIX the backslash is a valid character inside a path component, i.e., it's not a separator. On Windows, the forward slash and the backward slash are both separators. Instead please use/orpathmethods.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: '**/*',
to: 'relative/path/to/dest/',
},
{
from: '**/*',
to: '/absolute/path/to/dest/',
},
{
from: '**/*',
to: '[path][name].[contenthash].[ext]',
},
],
}),
],
}; contextType: String Default: options.context|compiler.options.context
A path that determines how to interpret the from path.
⚠️ Don't use directly
\\incontext(i.epath\to\context) option because on UNIX the backslash is a valid character inside a path component, i.e., it's not a separator. On Windows, the forward slash and the backward slash are both separators. Instead please use/orpathmethods.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.txt',
to: 'dest/',
context: 'app/',
},
],
}),
],
}; The context option can be an absolute or relative path. If context is a relative, then it is converted to absolute based to compiler.options.context
Also, context indicates how to interpret the search results. Further, he is considered in this role.
To determine the structure from which the found resources will be copied to the destination folder, the context option is used.
If from is a file, then context is equal to the directory in which this file is located. Accordingly, the result will be only the file name.
If from is a directory, then context is the same as from and is equal to the directory itself. In this case, the result will be a hierarchical structure of the found folders and files relative to the specified directory.
If from is a glob, then regardless of the context option, the result will be the structure specified in the from option
More examples
globOptionsType: Object Default: undefined
Allows to configute the glob pattern matching library used by the plugin. See the list of supported options To exclude files from the selection, you should use globOptions.ignore option
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'public/**/*',
globOptions: {
dot: true,
gitignore: true,
ignore: ['**/file.*', '**/ignored-directory/**'],
},
},
],
}),
],
}; filterType: Function Default: undefined
ℹ️ To ignore files by path please use the [
globOptions.ignore](https://github.com/webpack-contrib/copy-webpack-plugin/blob/master/(#globoptions) option.
webpack.config.js
const fs = require('fs').promise;
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'public/**/*',
filter: async (resourcePath) => {
const data = await fs.promises.readFile(resourcePath);
const content = data.toString();
if (content === 'my-custom-content') {
return false;
}
return true;
},
},
],
}),
],
}; toTypeType: String Default: undefined
Determinate what is to option - directory, file or template. Sometimes it is hard to say what is to, example path/to/dir-with.ext. If you want to copy files in directory you need use dir option. We try to automatically determine the type so you most likely do not need this option.
| Name | Type | Default | Description |
|---|---|---|---|
Name Type Default Description
| {String} | undefined | If to has no extension or ends on '/' |
Name Type Default Description
| {String} | undefined | If to is not a directory and is not a template |
Name Type Default Description
| {String} | undefined | If to contains a template pattern |
'dir'webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'path/to/file.txt',
to: 'directory/with/extension.ext',
toType: 'dir',
},
],
}),
],
}; 'file'webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'path/to/file.txt',
to: 'file/without/extension',
toType: 'file',
},
],
}),
],
}; 'template'webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/',
to: 'dest/[name].[hash].[ext]',
toType: 'template',
},
],
}),
],
}; forceType: Boolean Default: false
Overwrites files already in compilation.assets (usually added by other plugins/loaders).
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/**/*',
to: 'dest/',
force: true,
},
],
}),
],
}; flattenType: Boolean Default: false
Removes all directory references and only copies file names.
⚠️ If files have the same name, the result is non-deterministic.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/**/*',
to: 'dest/',
flatten: true,
},
],
}),
],
}; transformType: Function Default: undefined
Allows to modify the file contents.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
// The `content` argument is a [`Buffer`](https://nodejs.org/api/buffer.html) object, it could be converted to a `String` to be processed using `content.toString()`
// The `absoluteFrom` argument is a `String`, it is absolute path from where the file is being copied
transform(content, absoluteFrom) {
return optimize(content);
},
},
],
}),
],
}; webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
transform(content, path) {
return Promise.resolve(optimize(content));
},
},
],
}),
],
}; cacheTransformType: Boolean|String|Object Default: false
Enable/disable and configure caching. Default path to cache directory: node_modules/.cache/copy-webpack-plugin.
BooleanEnables/Disable transform caching.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
transform(content, path) {
return optimize(content);
},
cacheTransform: true,
},
],
}),
],
}; StringEnables transform caching and setup cache directory.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
transform(content, path) {
return optimize(content);
},
// Should be absolute
cacheTransform: path.resolve(__dirname, 'cache-directory'),
},
],
}),
],
}; ObjectEnables transform caching and setup cache directory and invalidation keys.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
transform(content, path) {
return optimize(content);
},
cacheTransform: {
directory: path.resolve(__dirname, 'cache-directory'),
keys: {
// May be useful for invalidating cache based on external values
// For example, you can invalid cache based on `process.version` - { node: process.version }
key: 'value',
},
},
},
],
}),
],
}; You can setup invalidation keys using a function.
Simple function:
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
transform(content, path) {
return optimize(content);
},
cacheTransform: {
directory: path.resolve(__dirname, 'cache-directory'),
keys: (defaultCacheKeys, absoluteFrom) => {
const keys = getCustomCacheInvalidationKeysSync();
return {
...defaultCacheKeys,
keys,
};
},
},
},
],
}),
],
}; Async function:
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
transform(content, path) {
return optimize(content);
},
cacheTransform: {
directory: path.resolve(__dirname, 'cache-directory'),
keys: async (defaultCacheKeys, absoluteFrom) => {
const keys = await getCustomCacheInvalidationKeysAsync();
return {
...defaultCacheKeys,
keys,
};
},
},
},
],
}),
],
}; transformPathType: Function Default: undefined
Allows to modify the writing path.
⚠️ Don't return directly
\\intransformPath(i.epath\to\newFile) option because on UNIX the backslash is a valid character inside a path component, i.e., it's not a separator. On Windows, the forward slash and the backward slash are both separators. Instead please use/orpathmethods.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
transformPath(targetPath, absolutePath) {
return 'newPath';
},
},
],
}),
],
}; webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
transformPath(targetPath, absolutePath) {
return Promise.resolve('newPath');
},
},
],
}),
],
}; noErrorOnMissingType: Boolean Default: false
Doesn't generate an error on missing file(s);
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, 'missing-file.txt'),
noErrorOnMissing: true,
},
],
}),
],
}; | Name | Type | Default | Description |
|---|---|---|---|
Name Type Default Description
| {Number} | 100 | Limits the number of simultaneous requests to fs |
concurrencylimits the number of simultaneous requests to fs
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [...patterns],
options: { concurrency: 50 },
}),
],
}; from (glob, file or dir).Take for example the following file structure:
src/directory-nested/deep-nested/deepnested-file.txt
src/directory-nested/nested-file.txt
Everything that you specify in from will be included in the result:
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/directory-nested/**/*',
},
],
}),
],
}; Result:
src/directory-nested/deep-nested/deepnested-file.txt,
src/directory-nested/nested-file.txt
If you want only content src/directory-nested/, you should only indicate glob in from. The path to the folder in which the search should take place, should be moved to context.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: '**/*',
context: path.resolve(__dirname, 'src', 'directory-nested'),
},
],
}),
],
}; Result:
deep-nested/deepnested-file.txt,
nested-file.txt
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, 'src', 'directory-nested'),
},
],
}),
],
}; Result:
deep-nested/deepnested-file.txt,
nested-file.txt
Technically, this is **/* with a predefined context equal to the specified directory.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: '**/*',
context: path.resolve(__dirname, 'src', 'directory-nested'),
},
],
}),
],
}; Result:
deep-nested/deepnested-file.txt,
nested-file.txt
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(
__dirname,
'src',
'directory-nested',
'nested-file.txt'
),
},
],
}),
],
}; Result:
nested-file.txt
Technically, this is a filename with a predefined context equal to path.dirname(pathToFile).
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'nested-file.txt',
context: path.resolve(__dirname, 'src', 'directory-nested'),
},
],
}),
],
}; Result:
nested-file.txt
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.posix.join(
path.resolve(__dirname, 'src').replace(/\\/g, '/'),
'**/*'
),
globOptions: {
ignore: [
// Ignore all `txt` files
'**/*.txt',
// Ignore all files in all subdirectories
'**/subdir/**',
],
},
},
],
}),
],
}; Please take a moment to read our contributing guidelines if you haven't yet done so.
This plugin uses cssnano to optimize and minify your CSS.
Just like optimize-css-assets-webpack-plugin but more accurate with source maps and assets using query string, allows to cache and works in parallel mode.
To begin, you'll need to install css-minimizer-webpack-plugin:
$ npm install css-minimizer-webpack-plugin --save-dev
Then add the plugin to your webpack configuration. For example:
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
module: {
loaders: [
{
test: /.s?css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
],
},
optimization: {
minimize: true,
minimizer: [
// For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
// `...`
new CssMinimizerPlugin(),
],
},
}; This will enable CSS optimization only in production mode. If you want to run it also in development set the optimization.minimize option to true.
And run webpack via your preferred method.
testType: String|RegExp|Array<String|RegExp> - default: /\.css(\?.*)?$/i
Test to match files against.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
test: /\.foo\.css$/i,
}),
],
},
}; includeType: String|RegExp|Array<String|RegExp> Default: undefined
Files to include.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
include: /\/includes/,
}),
],
},
}; excludeType: String|RegExp|Array<String|RegExp> Default: undefined
Files to exclude.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
exclude: /\/excludes/,
}),
],
},
}; cache⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache.
Type: Boolean|String Default: true
Enable file caching. Default path to cache directory: node_modules/.cache/css-minimizer-webpack-plugin.
ℹ️ If you use your own
minifyfunction please read theminifysection for cache invalidation correctly.
BooleanEnable/disable file caching.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
cache: true,
}),
],
},
}; StringEnable file caching and set path to cache directory.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
cache: 'path/to/cache',
}),
],
},
}; cacheKeys⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache.
Type: Function<(defaultCacheKeys, file) -> Object> Default: defaultCacheKeys => defaultCacheKeys
Allows you to override default cache keys.
Default cache keys:
({
cssMinimizer: require('cssnano/package.json').version, // cssnano version
'css-minimizer-webpack-plugin': require('../package.json').version, // plugin version
'css-minimizer-webpack-plugin-options': this.options, // plugin options
path: compiler.outputPath ? `${compiler.outputPath}/${file}` : file, // asset path
hash: crypto.createHash('md4').update(input).digest('hex'), // source file hash
}); webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
cache: true,
cacheKeys: (defaultCacheKeys, file) => {
defaultCacheKeys.myCacheKey = 'myCacheKeyValue';
return defaultCacheKeys;
},
}),
],
},
}; parallelType: Boolean|Number Default: true
Use multi-process parallel running to improve the build speed. Default number of concurrent runs: os.cpus().length - 1.
ℹ️ Parallelization can speedup your build significantly and is therefore highly recommended.
BooleanEnable/disable multi-process parallel running.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
parallel: true,
}),
],
},
}; NumberEnable multi-process parallel running and set number of concurrent runs.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
parallel: 4,
}),
],
},
}; sourceMapType: Boolean|Object Default: false (see below for details around devtool value and SourceMapDevToolPlugin plugin)
Enable (and configure) source map support. Use PostCss SourceMap options. Default configuration when enabled: { inline: false }.
Works only with source-map, inline-source-map, hidden-source-map and nosources-source-map values for the devtool option.
Why? Because CSS support only these source map types.
The plugin respect the devtool and using the SourceMapDevToolPlugin plugin. Using supported devtool values enable source map generation. Using SourceMapDevToolPlugin with enabled the columns option enables source map generation.
Use source maps to map error message locations to modules (this slows down the compilation). If you use your own minify function please read the minify section for handling source maps correctly.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
sourceMap: true,
}),
],
},
}; minifyType: Function Default: undefined
Allows you to override default minify function. By default plugin uses cssnano package. Useful for using and testing unpublished versions or forks.
⚠️ Always use
requireinsideminifyfunction whenparalleloption enabled.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
sourceMap: true,
minify: (data, inputMap, minimizerOptions) => {
const postcss = require('postcss');
const plugin = postcss.plugin(
'custom-plugin',
() => (css, result) => {
// custom code
}
);
const [[filename, input]] = Object.entries(data);
const postcssOptions = {
from: filename,
to: filename,
map: {
prev: inputMap,
},
};
return postcss([plugin])
.process(input, postcssOptions)
.then((result) => {
return {
css: result.css,
map: result.map,
warnings: result.warnings(),
};
});
},
}),
],
},
}; minimizerOptionsType: Object Default: { preset: 'default' }
Cssnano optimisations options.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
preset: [
'default',
{
discardComments: { removeAll: true },
},
],
},
}),
],
},
}; warningsFilterType: Function<(warning, file, source) -> Boolean> Default: () => true
Allow to filter css-minimizer warnings (By default cssnano). Return true to keep the warning, a falsy value (false/null/undefined) otherwise.
⚠️ The
sourceargument will containundefinedif you don't use source maps.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
warningsFilter: (warning, file, source) => {
if (/Dropping unreachable code/i.test(warning)) {
return true;
}
if (/file\.css/i.test(file)) {
return true;
}
if (/source\.css/i.test(source)) {
return true;
}
return false;
},
}),
],
},
}; Don't forget to enable sourceMap options for all loaders.
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
module: {
loaders: [
{
test: /.s?css$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { sourceMap: true } },
{ loader: 'sass-loader', options: { sourceMap: true } },
],
},
],
},
optimization: {
minimizer: [
new CssMinimizerPlugin({
sourceMap: true,
}),
],
},
}; Remove all comments (including comments starting with /*!).
module.exports = {
optimization: {
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
preset: [
'default',
{
discardComments: { removeAll: true },
},
],
},
}),
],
},
}; By default plugin uses cssnano package. It is possible to use another minify function.
⚠️ Always use
requireinsideminifyfunction whenparalleloption enabled.
webpack.config.js
module.exports = {
devtool: 'source-map',
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
sourceMap: true,
minify: async (data, inputMap) => {
const csso = require('csso');
const sourcemap = require('source-map');
const [[filename, input]] = Object.entries(data);
const minifiedCss = csso.minify(input, {
filename: filename,
sourceMap: true,
});
if (inputMap) {
minifiedCss.map.applySourceMap(
new sourcemap.SourceMapConsumer(inputMap),
filename
);
}
return {
css: minifiedCss.css,
map: minifiedCss.map.toJSON(),
};
},
}),
],
},
}; By default plugin uses cssnano package. It is possible to use another minify function.
⚠️ Always use
requireinsideminifyfunction whenparalleloption enabled.
webpack.config.js
module.exports = {
devtool: 'source-map',
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
sourceMap: true,
minify: async (data, inputMap) => {
// eslint-disable-next-line global-require
const CleanCSS = require('clean-css');
const [[filename, input]] = Object.entries(data);
const minifiedCss = await new CleanCSS({ sourceMap: true }).minify({
[filename]: https://github.com/webpack-contrib/css-minimizer-webpack-plugin/blob/master/%7B
styles: input,
sourceMap: inputMap,
},
});
return {
css: minifiedCss.styles,
map: minifiedCss.sourceMap.toJSON(),
warnings: minifiedCss.warnings,
};
},
}),
],
},
}; Please take a moment to read our contributing guidelines if you haven't yet done so.
The DefinePlugin allows you to create global constants which can be configured at compile time. This can be useful for allowing different behavior between development builds and production builds. If you perform logging in your development build but not in the production build you might use a global constant to determine whether logging takes place. That's where DefinePlugin shines, set it and forget it rules for development and production builds.
new webpack.DefinePlugin({
// Definitions...
}); Each key passed into DefinePlugin is an identifier or multiple identifiers joined with ..
typeof to the key, it's only defined for typeof calls.The values will be inlined into the code allowing a minification pass to remove the redundant conditional.
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true),
VERSION: JSON.stringify('5fa3b9'),
BROWSER_SUPPORTS_HTML5: true,
TWO: '1+1',
'typeof window': JSON.stringify('object'),
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}); console.log('Running App version ' + VERSION);
if(!BROWSER_SUPPORTS_HTML5) require('html5shiv'); When defining values for
processprefer'process.env.NODE_ENV': JSON.stringify('production')overprocess: { env: { NODE_ENV: JSON.stringify('production') } }. Using the latter will overwrite theprocessobject which can break compatibility with some modules that expect other values on the process object to be defined.
Note that because the plugin does a direct text replacement, the value given to it must include actual quotes inside of the string itself. Typically, this is done either with alternate quotes, such as
'"production"', or by usingJSON.stringify('production').
if (!PRODUCTION) {
console.log('Debug info');
}
if (PRODUCTION) {
console.log('Production log');
} After passing through webpack with no minification results in:
if (!true) {
console.log('Debug info');
}
if (true) {
console.log('Production log');
} and then after a minification pass results in:
console.log('Production log'); Enable/disable features in production/development build using feature flags.
new webpack.DefinePlugin({
'NICE_FEATURE': JSON.stringify(true),
'EXPERIMENTAL_FEATURE': JSON.stringify(false)
}); Use a different service URL in production/development builds:
new webpack.DefinePlugin({
'SERVICE_URL': JSON.stringify('https://dev.example.com')
}); runtimeValuefunction (getterFunction, [string]) => getterFunction()
It is possible to define variables with values that rely on files and will be re-evaluated when such files change in the file system. This means webpack will rebuild when such watched files change.
Arguments:
webpack.DefinePlugin.runtimeValue is a function that should return the value to be assigned to the definition.true instead of [string] here to flag the module as uncacheable.const fileDep = path.resolve(__dirname, 'sample.txt');
new webpack.DefinePlugin({
BUILT_AT: webpack.DefinePlugin.runtimeValue(Date.now, [fileDep])
}); The value of BUILT_AT would be the time at which the 'sample.txt' was last updated in the file system, e.g. 1597953013291.
The DllPlugin and DllReferencePlugin provide means to split bundles in a way that can drastically improve build time performance. The term "DLL" stands for Dynamic-link library which was originally introduced by Microsoft.
DllPluginThis plugin is used in a separate webpack configuration exclusively to create a dll-only-bundle. It creates a manifest.json file, which is used by the DllReferencePlugin to map dependencies.
context (optional): context of requests in the manifest file (defaults to the webpack context.)format (boolean = false): If true, manifest json file (output) will be formatted.name: name of the exposed dll function (TemplatePaths: [fullhash] & [name] )path: absolute path to the manifest json file (output)entryOnly (boolean = true): if true, only entry points will be exposedtype: type of the dll bundlenew webpack.DllPlugin(options); We recommend using DllPlugin only with
entryOnly: true, otherwise tree shaking in the DLL won't work as all the exports might be used.
Creates a manifest.json which is written to the given path. It contains mappings from require and import requests to module ids. It is used by the DllReferencePlugin.
Combine this plugin with output.library option to expose (aka, put into the global scope) the dll function.
DllReferencePluginThis plugin is used in the primary webpack config, it references the dll-only-bundle(s) to require pre-built dependencies.
context: (absolute path) context of requests in the manifest (or content property)extensions: Extensions used to resolve modules in the dll bundle (only used when using 'scope').manifest : an object containing content and name or a string to the absolute path of the JSON manifest to be loaded upon compilationcontent (optional): the mappings from request to module id (defaults to manifest.content)name (optional): an identifier where the dll is exposed (defaults to manifest.name) (see also externals)scope (optional): prefix which is used for accessing the content of the dllsourceType (optional): how the dll is exposed (libraryTarget)new webpack.DllReferencePlugin(options); References a dll manifest file to map dependency names to module ids, then requires them as needed using the internal __webpack_require__ function.
Keep the
nameconsistent withoutput.library.
This plugin can be used in two different modes, scoped and mapped.
The content of the dll is accessible under a module prefix. i.e. with scope = 'xyz' a file abc in the dll can be access via require('xyz/abc').
The content of the dll is mapped to the current directory. If a required file matches a file in the dll (after resolving), then the file from the dll is used instead.
Because this happens after resolving every file in the dll bundle, the same paths must be available for the consumer of the dll bundle. i.e. if the dll contains lodash and the file abc, require('lodash') and require('./abc') will be used from the dll, rather than building them into the main bundle.
DllReferencePluginandDllPluginare used in separate webpack configs.
webpack.vendor.config.js
const path = require('path');
new webpack.DllPlugin({
context: __dirname,
name: '[name]_[fullhash]',
path: path.join(__dirname, 'manifest.json'),
}); webpack.app.config.js
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./manifest.json'),
scope: 'xyz',
sourceType: 'commonjs2'
}); Two separate example folders. Demonstrates scope and context.
Multiple
DllPluginsand multipleDllReferencePlugins.
The EnvironmentPlugin is shorthand for using the DefinePlugin on process.env keys.
The EnvironmentPlugin accepts either an array of keys or an object mapping its keys to their default values.
new webpack.EnvironmentPlugin(['NODE_ENV', 'DEBUG']); This is equivalent to the following DefinePlugin application:
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.DEBUG': JSON.stringify(process.env.DEBUG)
}); Not specifying the environment variable raises an "
EnvironmentPlugin-${key}environment variable is undefined" error.
Alternatively, the EnvironmentPlugin supports an object, which maps keys to their default values. The default value for a key is taken if the key is undefined in process.env.
new webpack.EnvironmentPlugin({
NODE_ENV: 'development', // use 'development' unless process.env.NODE_ENV is defined
DEBUG: false
}); Variables coming from
process.envare always strings.
Unlike
DefinePlugin, default values are applied toJSON.stringifyby theEnvironmentPlugin.
To specify an unset default value, use
nullinstead ofundefined.
If an environment variable is not found during bundling and no default value was provided, webpack will throw an error instead of a warning.
Example:
Let's investigate the result when running the previous EnvironmentPlugin configuration on a test file entry.js:
if (process.env.NODE_ENV === 'production') {
console.log('Welcome to production');
}
if (process.env.DEBUG) {
console.log('Debugging output');
} When executing NODE_ENV=production webpack in the terminal to build, entry.js becomes this:
if ('production' === 'production') { // <-- 'production' from NODE_ENV is taken
console.log('Welcome to production');
}
if (false) { // <-- default value is taken
console.log('Debugging output');
} Running DEBUG=false webpack yields:
if ('development' === 'production') { // <-- default value is taken
console.log('Welcome to production');
}
if ('false') { // <-- 'false' from DEBUG is taken
console.log('Debugging output');
} DotenvPluginThe third-party DotenvPlugin (dotenv-webpack) allows you to expose (a subset of) dotenv variables:
// .env
DB_HOST=127.0.0.1
DB_PASS=foobar
S3_API=mysecretkey new Dotenv({
path: './.env', // Path to .env file (this is the default)
safe: true // load .env.example (defaults to "false" which does not use dotenv-safe)
}); A ESLint plugin for webpack
The plugin was born with the purpose of solving some problems of the eslint-loader.
| eslint-webpack-plugin | eslint-loader | |
|---|---|---|
eslint-webpack-plugin eslint-loader Easy configuration :heavy_check_mark: | :heavy_check_mark: | :heavy_multiplication_x: |
eslint-webpack-plugin eslint-loader Generate unique an output report :heavy_check_mark: | :heavy_check_mark: | :heavy_multiplication_x: |
eslint-webpack-plugin eslint-loader Using cache directly from eslint :heavy_check_mark: | :heavy_check_mark: | :heavy_multiplication_x: |
eslint-webpack-plugin eslint-loader Lint only changed files :heavy_check_mark: | :heavy_check_mark: | :heavy_multiplication_x: |
eslint-loaderThe loader eslint-loader will be deprecated soon, please use this plugin instead.
Before:
module.exports = {
// ...
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
// eslint options (if necessary)
},
},
],
},
// ...
}; After:
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
// ...
plugins: [new ESLintPlugin(options)],
// ...
}; npm install eslint-webpack-plugin --save-dev Note: You also need to install eslint from npm, if you haven't already:
npm install eslint --save-dev In your webpack configuration:
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
// ...
plugins: [new ESLintPlugin(options)],
// ...
}; You can pass eslint options.
Note that the config option you provide will be passed to the ESLint class. This is a different set of options than what you'd specify in package.json or .eslintrc. See the eslint docs for more details.
Warning: In eslint-webpack-plugin version 1 the options were passed to the now deprecated CLIEngine.
contextStringcompiler.contextA string indicating the root of your files.
eslintPathStringeslintPath to eslint instance that will be used for linting. If the eslintPath is a folder like a official eslint, or specify a formatter option. now you dont have to install eslint.
filesString|Array[String]'.'Specify directories, files, or globs. Must be relative to options.context. Directories are traveresed recursively looking for files matching options.extensions. File and glob patterns ignore options.extensions.
extensionsString|Array[String]'js'Specify extensions that should be checked.
fixBooleanfalseWill enable ESLint autofix feature.
Be careful: this option will change source files.
formatterString|Function'stylish'Accepts a function that will have one argument: an array of eslint messages (object). The function must return the output as a string. You can use official eslint formatters.
lintDirtyModulesOnlyBooleanfalseLint only changed files, skip lint on start.
By default the plugin will auto adjust error reporting depending on eslint errors/warnings counts. You can still force this behavior by using emitError or emitWarning options:
emitErrorBooleanfalseWill always return errors, if set to true.
emitWarningBooleanfalseWill always return warnings, if set to true.
failOnErrorBooleanfalseWill cause the module build to fail if there are any errors, if set to true.
failOnWarningBooleanfalseWill cause the module build to fail if there are any warnings, if set to true.
quietBooleanfalseWill process and report errors only and ignore warnings, if set to true.
outputReportBoolean|ObjectfalseWrite the output of the errors to a file, for example a checkstyle xml file for use for reporting on Jenkins CI.
The filePath is an absolute path or relative to the webpack config: output.path. You can pass in a different formatter for the output file, if none is passed in the default/configured formatter will be used.
This plugin enables more fine grained control of source map generation. It is also enabled automatically by certain settings of the devtool configuration option.
new webpack.EvalSourceMapDevToolPlugin(options); The following options are supported:
test (string|RegExp|array): Include source maps for modules based on their extension (defaults to .js and .css).include (string|RegExp|array): Include source maps for module paths that match the given value.exclude (string|RegExp|array): Exclude modules that match the given value from source map generation.append (string): Appends the given value to the original asset. Usually the #sourceMappingURL comment. [url] is replaced with a URL to the source map file. false disables the appending.moduleFilenameTemplate (string): See output.devtoolModuleFilenameTemplate.module (boolean): Indicates whether loaders should generate source maps (defaults to true).columns (boolean): Indicates whether column mappings should be used (defaults to true).protocol (string): Allows user to override default protocol (webpack-internal://)Setting
moduleand/orcolumnstofalsewill yield less accurate source maps but will also improve compilation performance significantly.
If you want to use a custom configuration for this plugin in development mode, make sure to disable the default one. I.e. set
devtool: false.
The following examples demonstrate some common use cases for this plugin.
You can use the following code to replace the configuration option devtool: eval-source-map with an equivalent custom plugin configuration:
module.exports = {
// ...
devtool: false,
plugins: [
new webpack.EvalSourceMapDevToolPlugin({})
]
}; The following code would exclude source maps for any modules in the vendor.js bundle:
new webpack.EvalSourceMapDevToolPlugin({
exclude: ['vendor.js']
}); This plugin will cause hashes to be based on the relative path of the module, generating a four character string as the module id. Suggested for use in production.
new webpack.ids.HashedModuleIdsPlugin({
// Options...
}); This plugin supports the following options:
context: The context directory (absolute path) for creating names.hashFunction: The hashing algorithm to use, defaults to 'md4'. All functions from Node.JS' crypto.createHash are supported.hashDigest: The encoding to use when generating the hash, defaults to 'base64'. All encodings from Node.JS' hash.digest are supported.hashDigestLength: The prefix length of the hash digest to use, defaults to 4. Note that some generated ids might be longer than specified here, to avoid module id collisions.Here's an example of how this plugin might be used:
new webpack.ids.HashedModuleIdsPlugin({
context: __dirname,
hashFunction: 'sha256',
hashDigest: 'hex',
hashDigestLength: 20
}); Enables Hot Module Replacement, otherwise known as HMR.
HMR should never be used in production.
Enabling HMR is easy and in most cases no options are necessary.
new webpack.HotModuleReplacementPlugin({
// Options...
}); This plugin uses html-minifier-terser to optimize and minify your HTML.
To begin, you'll need to install html-minimizer-webpack-plugin:
$ npm install html-minimizer-webpack-plugin --save-dev
Then add the plugin to your webpack configuration. For example:
webpack.config.js
const HtmlMinimizerPlugin = require('html-minimizer-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
module: {
loaders: [
{
test: /\.html$/i,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
},
},
],
},
],
},
plugins: [
new CopyPlugin({
patterns: [
{
context: path.resolve(__dirname, 'dist'),
from: './src/*.html',
},
],
}),
],
optimization: {
minimize: true,
minimizer: [
// For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
// `...`
new HtmlMinimizerPlugin(),
],
},
}; This will enable HTML optimization only in production mode. If you want to run it also in development set the optimization.minimize option to true.
And run webpack via your preferred method.
testType: String|RegExp|Array<String|RegExp> - default: /\.html(\?.*)?$/i
Test to match files against.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
test: /\.foo\.html/i,
}),
],
},
}; includeType: String|RegExp|Array<String|RegExp> Default: undefined
Files to include.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
include: /\/includes/,
}),
],
},
}; excludeType: String|RegExp|Array<String|RegExp> Default: undefined
Files to exclude.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
exclude: /\/excludes/,
}),
],
},
}; cache⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache.
Type: Boolean|String Default: true
Enable file caching. Default path to cache directory: node_modules/.cache/html-minimizer-webpack-plugin.
ℹ️ If you use your own
minifyfunction please read theminifysection for cache invalidation correctly.
BooleanEnable/disable file caching.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
cache: true,
}),
],
},
}; StringEnable file caching and set path to cache directory.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
cache: 'path/to/cache',
}),
],
},
}; cacheKeys⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache.
Type: Function<(defaultCacheKeys, file) -> Object> Default: defaultCacheKeys => defaultCacheKeys
Allows you to override default cache keys.
Default cache keys:
({
htmlMinimizer: require('html-minifier-terser/package.json').version, // html-minifier-terser version
'html-minimizer-webpack-plugin': require('../package.json').version, // plugin version
'html-minimizer-webpack-plugin-options': this.options, // plugin options
nodeVersion: process.version, // Node.js version
assetName: file, // asset path
contentHash: crypto.createHash('md4').update(input).digest('hex'), // source file hash
}); webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
cache: true,
cacheKeys: (defaultCacheKeys, file) => {
defaultCacheKeys.myCacheKey = 'myCacheKeyValue';
return defaultCacheKeys;
},
}),
],
},
}; parallelType: Boolean|Number Default: true
Use multi-process parallel running to improve the build speed. Default number of concurrent runs: os.cpus().length - 1.
ℹ️ Parallelization can speedup your build significantly and is therefore highly recommended.
BooleanEnable/disable multi-process parallel running.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
parallel: true,
}),
],
},
}; NumberEnable multi-process parallel running and set number of concurrent runs.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
parallel: 4,
}),
],
},
}; minifyType: Function Default: undefined
Allows you to override default minify function. By default plugin uses html-minifier-terser package. Useful for using and testing unpublished versions or forks.
⚠️ Always use
requireinsideminifyfunction whenparalleloption enabled.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
minimizerOptions: {
collapseWhitespace: true,
},
minify: (data, minimizerOptions) => {
const htmlMinifier = require('html-minifier-terser');
const [[filename, input]] = Object.entries(data);
return htmlMinifier.minify(input, minimizerOptions);
},
}),
],
},
}; minimizerOptionsType: Object Default: { caseSensitive: true, collapseWhitespace: true, conservativeCollapse: true, keepClosingSlash: true, minifyCSS: true, minifyJS: true, removeComments: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, }
Html-minifier-terser optimisations options.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
minimizerOptions: {
collapseWhitespace: false,
},
}),
],
},
}; Please take a moment to read our contributing guidelines if you haven't yet done so.
The HtmlWebpackPlugin simplifies creation of HTML files to serve your webpack bundles. This is especially useful for webpack bundles that include a hash in the filename which changes every compilation. You can either let the plugin generate an HTML file for you, supply your own template using lodash templates, or use your own loader.
npm install --save-dev html-webpack-plugin The plugin will generate an HTML5 file for you that includes all your webpack bundles in the body using script tags. Just add the plugin to your webpack configuration as follows:
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
module.exports = {
entry: 'index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'index_bundle.js'
},
plugins: [new HtmlWebpackPlugin()]
}; This will generate a file dist/index.html containing the following:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webpack App</title>
</head>
<body>
<script src="index_bundle.js"></script>
</body>
</html> If you have multiple webpack entry points, they will all be included with <script> tags in the generated HTML.
If you have any CSS assets in webpack's output (for example, CSS extracted with the MiniCssExtractPlugin) then these will be included with <link> tags in the <head> element of generated HTML.
For all configuration options, please see the plugin documentation.
The plugin supports addons. For a list see the documentation.
IgnorePlugin prevents the generation of modules for import or require calls matching the regular expressions or filter functions:
resourceRegExp: A RegExp to test the resource against.contextRegExp: (optional) A RegExp to test the context (directory) against.new webpack.IgnorePlugin({resourceRegExp, contextRegExp});
// Supported in webpack 4 and earlier, unsupported in webpack 5:
new webpack.IgnorePlugin(resourceRegExp, [contextRegExp]); checkResource (resource, context) A Filter function that receives resource and context as arguments, must return boolean.checkContext (context) was removed in webpack 5 as checkResource already gets context.new webpack.IgnorePlugin({
checkResource (resource) {
// do something with resource
return true|false;
}
}); As of moment 2.18, all locales are bundled together with the core library (see this GitHub issue).
The resourceRegExp parameter passed to IgnorePlugin is not tested against the resolved file names or absolute module names being imported or required, but rather against the string passed to require or import within the source code where the import is taking place. For example, if you're trying to exclude node_modules/moment/locale/*.js, this won't work:
-new webpack.IgnorePlugin({requestRegExp: /moment\/locale\//}); Rather, because moment imports with this code:
require('./locale/' + name); ...your first regexp must match that './locale/' string. The second contextRegExp parameter is then used to select specific directories from where the import took place. The following will cause those locale files to be ignored:
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/
}); ...which means "any require statement matching './locale' from any directories ending with 'moment' will be ignored.
Plugin and Loader for <a href="http://webpack.js.org/">webpack</a> to optimize (compress) all images using <a href="https://github.com/imagemin/imagemin">imagemin</a>.
Do not worry about size of images, now they are always optimized/compressed.
This plugin uses imagemin to optimize your images.
To begin, you'll need to install image-minimizer-webpack-plugin:
$ npm install image-minimizer-webpack-plugin --save-dev
Images can be optimized in two modes:
Note:
Explore the options to get the best result for you.
Recommended imagemin plugins for lossless optimization
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev Recommended imagemin plugins for lossy optimization
npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: 'file-loader', // Or `url-loader` or your other loader
},
],
},
],
},
plugins: [
new ImageMinimizerPlugin({
minimizerOptions: {
// Lossless optimization with custom option
// Feel free to experiment with options for better result for you
plugins: [
['gifsicle', { interlaced: true }],
['jpegtran', { progressive: true }],
['optipng', { optimizationLevel: 5 }],
[
'svgo',
{
plugins: [
{
removeViewBox: false,
},
],
},
],
],
},
}),
],
}; ℹ️ Only for
4version ofwebpack: Make sure that plugin place after any plugins that add images or other assets which you want to optimized.**
ℹ️ If you want to use
loaderorpluginstandalone see sections below, but this is not recommended.
In your webpack.config.js, add the ImageMinimizerPlugin.loader, chained with the file-loader or url-loader:
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: 'file-loader', // Or `url-loader` or your other loader
},
{
loader: ImageMinimizerPlugin.loader,
options: {
severityError: 'warning', // Ignore errors on corrupted images
minimizerOptions: {
plugins: ['gifsicle'],
},
},
},
],
},
],
},
}; webpack.config.js
const ImageminWebpack = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
},
test: /\.(jpe?g|png|gif|svg)$/i,
},
],
},
plugins: [
// Make sure that the plugin placed after any plugins that added images
new ImageminWebpack({
severityError: 'warning', // Ignore errors on corrupted images
minimizerOptions: {
plugins: ['gifsicle'],
},
// Disable `loader`
loader: false,
}),
],
}; | Name | Type | Default | Description |
|---|---|---|---|
Name Type Default Description
| {String\/RegExp\|Array<String\|RegExp>} | /.(jpe?g|png|gif|tif|webp|svg|avif)\$/i | Test to match files against |
Name Type Default Description
| {String\/RegExp\|Array<String\|RegExp>} | undefined | Files to include |
Name Type Default Description
| {String\/RegExp\|Array<String\|RegExp>} | undefined | Files to exclude |
Name Type Default Description
| {Function} | () => true | Allows filtering of images for optimization |
Name Type Default Description
| {Boolean\|String} | true | Enable file caching |
Name Type Default Description
| {Boolean\|String} | 'auto' | Allows to choose how errors are displayed |
Name Type Default Description
| {Object} | { plugins: [] } | Options for imagemin |
Name Type Default Description
| {Boolean} | true | Automatically adding imagemin-loader (require for minification images using in url-loader, svg-url-loader or other) |
Name Type Default Description
| {Number} | Math.max(1, os.cpus().length - 1) | Maximum number of concurrency optimization processes in one time |
Name Type Default Description
| {string} | '[path][name][ext]' | Allows to set the filename for the generated asset. Useful for converting to a webp |
Name Type Default Description
| {Boolean} | false | Allows to delete the original asset. Useful for converting to a webp and remove original assets |
testType: String|RegExp|Array<String|RegExp> Default: /\.(jpe?g\|png\|gif\|tif\|webp\|svg\|avif)\$/i
Test to match files against.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
test: /\.(jpe?g|png|gif|svg)$/i,
}),
],
}; includeType: String|RegExp|Array<String|RegExp> Default: undefined
Files to include.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
include: /\/includes/,
}),
],
}; excludeType: String|RegExp|Array<String|RegExp> Default: undefined
Files to exclude.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
exclude: /\/excludes/,
}),
],
}; filterType: Function Default: () => true
Allows filtering of images for optimization.
Return true to optimize the image, false otherwise.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
filter: (source, sourcePath) => {
// The `source` argument is a `Buffer` of source file
// The `sourcePath` argument is an absolute path to source
if (source.byteLength < 8192) {
return false;
}
return true;
},
}),
],
}; cache⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache.
Type: Boolean|String Default: true
Enable/disable file caching. Default path to cache directory: node_modules/.cache/image-minimizer-webpack-plugin.
{Boolean}Enable/disable file caching.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
cache: false,
}),
],
}; {String}Enable file caching and set path to cache directory.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
cache: 'path/to/cache',
}),
],
}; severityErrorType: Boolean|String Default: 'auto'
Allows to choose how errors are displayed.
Сan have the following values:
'auto' - emit warnings in development mode and emit errors in production mode (default behavior)false or 'off' - suppresses errors and warnings'warning' - emit warnings instead errorstrue or 'error' - emit errorswebpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
severityError: 'warning',
}),
],
}; minimizerOptionsType: Object Default: { plugins: [] }
Options for imagemin.
More information and examples here.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
minimizerOptions: {
plugins: [
// Name
'gifsicle',
// Name with options
['mozjpeg', { quality: 80 }],
// Full package name
[
'imagemin-svgo',
{
plugins: [
{
removeViewBox: false,
},
],
},
],
[
// Custom package name
'nonstandard-imagemin-package-name',
{ myOptions: true },
],
],
},
}),
],
}; loaderType: Boolean Default: true
Automatically adding imagemin-loader.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
loader: false,
}),
],
}; maxConcurrencyType: Number Default: Math.max(1, os.cpus().length - 1)
Maximum number of concurrency optimization processes in one time.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
maxConcurrency: 3,
}),
],
}; filenameType: String Default: '[path][name][ext]'
Allows to set the filename for the generated asset. Useful for converting to a webp.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
// Images are converted to `webp` and the original assets have been kept
new ImageMinimizerPlugin({
test: /\.(png)$/i,
filename: '[path][name].webp',
minimizerOptions: {
plugins: ['imagemin-webp'],
},
}),
],
}; deleteOriginalAssetsType: Boolean Default: false
Allows to remove original assets. Useful for converting to a webp and remove original assets
i Doesn't make sense if you haven't changed the original value of the
filenameoption
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
// Images are converted to `webp` and the original assets have been removed
new ImageMinimizerPlugin({
test: /\.(png)$/i,
deleteOriginalAssets: true,
filename: '[path][name].webp',
minimizerOptions: {
plugins: ['imagemin-webp'],
},
}),
],
}; To generate and compress the original assets:
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
// And the original assets will be compressed
new ImageMinimizerPlugin({
test: /\.(png)$/i,
minimizerOptions: {
plugins: ['pngquant'],
},
}),
// Images are converted to `webp` and the original assets have been removed
new ImageMinimizerPlugin({
test: /\.(png)$/i,
deleteOriginalAssets: false,
filename: '[path][name].webp',
minimizerOptions: {
plugins: ['imagemin-webp'],
},
}),
],
}; | Name | Type | Default | Description |
|---|---|---|---|
Name Type Default Description
| {Function} | undefined | Allows filtering of images for optimization |
Name Type Default Description
| {Boolean\|String} | true | Enable file caching |
Name Type Default Description
| {Boolean\|String} | 'auto' | Allows to choose how errors are displayed |
Name Type Default Description
| {Object} | { plugins: [] } | Options for imagemin |
Name Type Default Description
| {string} | '[path][name][ext]' | Allows to set the filename for the generated asset. Useful for converting to a webp |
Name Type Default Description
| {Boolean} | false | Allows to delete the original asset. Useful for converting to a webp and remove original assets |
filterType: Function Default: () => true
Allows filtering of images for optimization.
Return true to optimize the image, false otherwise.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: 'file-loader', // Or `url-loader` or your other loader
},
{
loader: ImageMinimizerPlugin.loader,
options: {
cache: true,
filter: (source, sourcePath) => {
// The `source` argument is a `Buffer` of source file
// The `sourcePath` argument is an absolute path to source
if (source.byteLength < 8192) {
return false;
}
return true;
},
minimizerOptions: {
plugins: ['gifsicle'],
},
},
},
],
},
],
},
}; cacheType: Boolean\|String Default: true
Enable file caching. Default path to cache directory: node_modules/.cache/image-minimizer-webpack-plugin.
{Boolean}Enable/disable file caching.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: 'file-loader', // Or `url-loader` or your other loader
},
{
loader: ImageMinimizerPlugin.loader,
options: {
cache: false,
minimizerOptions: {
plugins: ['gifsicle'],
},
},
},
],
},
],
},
}; {String}Enable file caching and set path to cache directory.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: 'file-loader', // Or `url-loader` or your other loader
},
{
loader: ImageMinimizerPlugin.loader,
options: {
cache: 'path/to/cache',
minimizerOptions: {
plugins: ['gifsicle'],
},
},
},
],
},
],
},
}; severityErrorType: Boolean|String Default: 'auto'
Allows to choose how errors are displayed.
Сan have the following values:
'auto' - emit warnings in development mode and emit errors in production mode (default behavior)false or 'off' - suppresses errors and warnings'warning' - emit warnings instead errorstrue or 'error' - emit errorswebpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: 'file-loader', // Or `url-loader` or your other loader
},
{
loader: ImageMinimizerPlugin.loader,
options: {
severityError: 'warning',
minimizerOptions: {
plugins: ['gifsicle'],
},
},
},
],
},
],
},
}; minimizerOptionsType: Object Default: { plugins: [] }
Options for imagemin.
Options for imagemin
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: 'file-loader', // Or `url-loader` or your other loader
},
{
loader: ImageMinimizerPlugin.loader,
options: {
severityError: 'warning',
minimizerOptions: {
plugins: [
['gifsicle', { interlaced: true, optimizationLevel: 3 }],
],
},
},
},
],
},
],
},
}; filenameType: String Default: '[path][name][ext]'
Allows to set the filename for the generated asset. Useful for converting to a webp.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif)$/i,
use: [
{
loader: 'file-loader', // Or `url-loader` or your other loader
},
{
loader: ImageMinimizerPlugin.loader,
options: {
filename: '[path][name].webp',
minimizerOptions: {
plugins: ['imagemin-webp'],
},
},
},
],
},
],
},
}; deleteOriginalAssetsType: Boolean Default: false
Allows to keep the original asset. Useful for converting to a webp and remove original assets.
i Doesn't make sense if you haven't changed the original value of the
filenameoption
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(png)$/i,
use: [
{
loader: 'file-loader', // Or `url-loader` or your other loader
},
{
loader: ImageMinimizerPlugin.loader,
options: {
// PNG images are converted to WEBP, and the originals will keep
deleteOriginalAssets: false,
filename: '[path][name].webp',
minimizerOptions: {
plugins: ['imagemin-webp'],
},
},
},
],
},
],
},
}; normalizeConfig(config)The function normalizes configuration (converts plugins names and options to Functions) for using in imagemin package directly.
const imagemin = require('imagemin');
const { normalizeConfig } = require('image-minimizer-webpack-plugin');
const imageminConfig = normalizeConfig({
plugins: [
'jpegtran',
[
'pngquant',
{
quality: [0.6, 0.8],
},
],
],
});
/*
console.log(imageminConfig);
=>
{
plugins: [Function, Function],
pluginsMeta: [
{ name: "imagemin-jpegtran", version: "x.x.x", options: {} },
{ name: "imagemin-pngquant", version: "x.x.x", options: { quality: [0.6, 0.8] }
]
}
*/
(async () => {
const files = await imagemin(['images/*.{jpg,png}'], {
destination: 'build/images',
plugins: imageminConfig.plugins,
});
console.log(files);
// => [{data: <Buffer 89 50 4e …>, path: 'build/images/foo.jpg'}, …]
})(); You can use difference options (like progressive/interlaced and etc) based on image size (example - don't do progressive transformation for small images).
What is progressive image? Answer here.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
minimizer: [
new ImageMinimizerPlugin({
// Only apply this one to files equal to or over 8192 bytes
filter: (source) => {
if (source.byteLength >= 8192) {
return true;
}
return false;
},
minimizerOptions: {
plugins: [['jpegtran', { progressive: true }]],
},
}),
new ImageMinimizerPlugin({
// Only apply this one to files under 8192
filter: (source) => {
if (source.byteLength < 8192) {
return true;
}
return false;
},
minimizerOptions: {
plugins: [['jpegtran', { progressive: false }]],
},
}),
],
}; webpconst ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
minimizerOptions: {
plugins: ['pngquant'],
},
}),
new ImageMinimizerPlugin({
deleteOriginalAssets: false,
filename: '[path][name].webp',
minimizerOptions: {
plugins: ['imagemin-webp'],
},
}),
],
}; Please take a moment to read our contributing guidelines if you haven't yet done so.
This is a list of plugins which are used by webpack internally.
You should only care about them if you are building your own compiler based on webpack, or introspect the internals.
Categories of internal plugins:
Plugins affecting the environment of the compiler.
webpack.node.NodeEnvironmentPlugin()
Applies Node.js style filesystem to the compiler.
Plugins affecting the compiler
MemoryCachePlugin()
Adds a cache to the compiler, where modules are cached in memory.
ProgressPlugin(handler)
Hook into the compiler to extract progress information. The handler must have the signature function(percentage, message). Percentage is called with a value between 0 and 1, where 0 indicates the start and 1 the end.
RecordIdsPlugin()
Saves and restores module and chunk ids from records.
Plugins, which add entry chunks to the compilation.
SingleEntryPlugin(context, request, chunkName)
Adds an entry chunk on compilation. The chunk is named chunkName and contains only one module (plus dependencies). The module is resolved from request in context (absolute path).
PrefetchPlugin(context, request)
Prefetches request and dependencies to enable a more parallel compilation. It doesn't create any chunk. The module is resolved from request in context (absolute path).
JsonpTemplatePlugin(options)
Chunks are wrapped into JSONP-calls. A loading algorithm is included in entry chunks. It loads chunks by adding a <script> tag.
options are the output options.
options.jsonpFunction is the JSONP function.
options.publicPath is used as path for loading the chunks.
options.chunkFilename is the filename under that chunks are expected.
node/NodeTemplatePlugin(options)
Chunks are wrapped into Node.js modules exporting the bundled modules. The entry chunks loads chunks by requiring them.
options are the output options.
options.chunkFilename is the filename under that chunks are expected.
LibraryTemplatePlugin(name, target)
The entries chunks are decorated to form a library name of type type.
webworker/WebWorkerTemplatePlugin(options)
Chunks are loaded by importScripts. Else it's similar to JsonpTemplatePlugin.
options are the output options.
Decorates the module template by wrapping each module in a eval annotated with // @sourceURL.
SourceMapDevToolPlugin(sourceMapFilename, sourceMappingURLComment, moduleFilenameTemplate, fallbackModuleFilenameTemplate)
Decorates the templates by generating a SourceMap for each chunk.
sourceMapFilename the filename template of the SourceMap. [hash], [name], [id], [file] and [filebase] are replaced. If this argument is missing, the SourceMap will be inlined as DataUrl.
HotModuleReplacementPlugin(options)
Add support for hot module replacement. Decorates the templates to add runtime code. Adds module.hot API.
options.hotUpdateChunkFilename the filename for hot update chunks.
options.hotUpdateMainFilename the filename for the hot update manifest.
options.hotUpdateFunction JSON function name for the hot update.
Plugins affecting the source code of modules.
Make webpack_public_path, webpack_require, webpack_modules and webpack_chunk_load accessible. Ensures that require.valueOf and require.onError are not processed by other plugins.
Currently useless. Ensures compatibility with other module loaders.
Tries to evaluate expressions in if (...) statements and ternaries to replace them with true/false for further possible dead branch elimination using hooks fired by the parser.
There are multiple optimizations in production mode regarding dead branches:
webpack will try to evaluate conditional statements. If it succeeds then the dead branch is removed. webpack can't do constant folding unless the compiler knows it. For example:
import { calculateTax } from './tax';
const FOO = 1;
if (FOO === 0) {
// dead branch
calculateTax();
} In the above example, webpack is unable to prune the branch, but Terser does. However, if FOO is defined using DefinePlugin, webpack will succeed.
It is important to mention that import { calculateTax } from './tax'; will also get pruned because calculateTax() call was in the dead branch and got eliminated.
ProvidePlugin(name, request)
If name is used in a module it is filled by a module loaded by require(<request>).
NodeStuffPlugin(options, context)
Provide stuff that is normally available in Node.js modules.
It also ensures that module is filled with some Node.js stuff if you use it.
Provide stuff that is normally available in require.js.
require[js].config is removed. require.version is 0.0.0. requirejs.onError is mapped to require.onError.
node/NodeSourcePlugin(options)
This module adds stuff from Node.js that is not available in non Node.js environments.
It adds polyfills for process, console, Buffer and global if used. It also binds the built in Node.js replacement modules.
node/NodeTargetPlugin()
The plugins should be used if you run the bundle in a Node.js environment.
If ensures that native modules are loaded correctly even if bundled.
dependencies/AMDPlugin(options)
Provides AMD-style define and require to modules. Also bind require.amd, define.amd and webpack_amd_options## to the options passed as parameter.
dependencies/CommonJsPlugin
Provides CommonJs-style require to modules.
dependencies/RequireContextPlugin(modulesDirectories, extensions)
Provides require.context. The parameter modulesDirectories and extensions are used to find alternative requests for files. It's useful to provide the same arrays as you provide to the resolver.
dependencies/RequireEnsurePlugin()
Provides require.ensure.
dependencies/RequireIncludePlugin()
Provides require.include.
DefinePlugin(definitions)
Define constants for identifier.
definitions is an object.
optimize/LimitChunkCountPlugin(options)
Merge chunks limit chunk count is lower than options.maxChunks.
The overhead for each chunks is provided by options.chunkOverhead or defaults to 10000. Entry chunks sizes are multiplied by options.entryChunkMultiplicator (or 10).
Chunks that reduce the total size the most are merged first. If multiple combinations are equal the minimal merged size wins.
optimize/MergeDuplicateChunksPlugin()
Chunks with the same modules are merged.
optimize/RemoveEmptyChunksPlugin()
Modules that are included in every parent chunk are removed from the chunk.
optimize/MinChunkSizePlugin(minChunkSize)
Merges chunks until each chunk has the minimum size of minChunkSize.
optimize/FlagIncludedChunksPlugin()
Adds chunk ids of chunks which are included in the chunk. This eliminates unnecessary chunk loads.
This plugin uses JSON.stringify() to minify your JSON.
To begin, you'll need to install json-minimizer-webpack-plugin:
$ npm install json-minimizer-webpack-plugin --save-dev
Then add the plugin to your webpack configuration. For example:
webpack.config.js
const JsonMinimizerPlugin = require('json-minimizer-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
module: {
loaders: [
{
test: /\.json/i,
type: 'javascript/auto',
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
},
},
],
},
],
},
plugins: [
new CopyPlugin({
patterns: [
{
context: path.resolve(__dirname, 'dist'),
from: './src/*.json',
},
],
}),
],
optimization: {
minimize: true,
minimizer: [
// For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
// `...`
new JsonMinimizerPlugin(),
],
},
}; This will enable JSON optimization only in production mode. If you want to run it also in development set the optimization.minimize option to true.
And run webpack via your preferred method.
testType: String|RegExp|Array<String|RegExp> - default: /\.json(\?.*)?$/i
Test to match files against.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
test: /\.foo\.json/i,
}),
],
},
}; includeType: String|RegExp|Array<String|RegExp> Default: undefined
Files to include.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
include: /\/includes/,
}),
],
},
}; excludeType: String|RegExp|Array<String|RegExp> Default: undefined
Files to exclude.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
exclude: /\/excludes/,
}),
],
},
}; cache⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache.
Type: Boolean|String Default: true
Enable file caching. Default path to cache directory: node_modules/.cache/json-minimizer-webpack-plugin.
BooleanEnable/disable file caching.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
cache: true,
}),
],
},
}; StringEnable file caching and set path to cache directory.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
cache: 'path/to/cache',
}),
],
},
}; cacheKeys⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache.
Type: Function<(defaultCacheKeys, file) -> Object> Default: defaultCacheKeys => defaultCacheKeys
Allows you to override default cache keys.
Default cache keys:
({
'json-minimizer-webpack-plugin': require('../package.json').version, // plugin version
'json-minimizer-webpack-plugin-options': this.options, // plugin options
nodeVersion: process.version, // Node.js version
assetName: file, // asset path
contentHash: crypto.createHash('md4').update(input).digest('hex'), // source file hash
}); webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
cache: true,
cacheKeys: (defaultCacheKeys, file) => {
defaultCacheKeys.myCacheKey = 'myCacheKeyValue';
return defaultCacheKeys;
},
}),
],
},
}; minimizerOptionsType: Object Default: { replacer: null, space: null }
JSON.stringify() options.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
minimizerOptions: {
space: '\t',
},
}),
],
},
}; Please take a moment to read our contributing guidelines if you haven't yet done so.
While writing your code, you may have already added many code split points to load stuff on demand. After compiling you might notice that some chunks are too small - creating larger HTTP overhead. LimitChunkCountPlugin can post-process your chunks by merging them.
new webpack.optimize.LimitChunkCountPlugin({
// Options...
}); The following options are supported:
maxChunksnumber
Limit the maximum number of chunks using a value greater than or equal to 1. Using 1 will prevent any additional chunks from being added as the entry/main chunk is also included in the count.
webpack.config.js
const webpack = require('webpack');
module.exports = {
// ...
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 5
})
]
}; minChunkSizeKeeping chunk size above the specified limit is no longer a feature of this plugin. Use [MinChunkSizePlugin)[/plugins/min-chunk-size-plugin] instead.
This plugin and it's options can also be invoked via the CLI:
webpack --optimize-max-chunks 15 Keep chunk size above the specified limit by merging chunks that are smaller than the minChunkSize.
new webpack.optimize.MinChunkSizePlugin({
minChunkSize: 10000 // Minimum number of characters
}); This plugin and it's options can also be invoked via the CLI:
webpack --optimize-min-chunk-size 10000 This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS. It supports On-Demand-Loading of CSS and SourceMaps.
It builds on top of a new webpack v4 feature (module types) and requires webpack 4 to work.
Compared to the extract-text-webpack-plugin:
To begin, you'll need to install mini-css-extract-plugin:
npm install --save-dev mini-css-extract-plugin It's recommended to combine mini-css-extract-plugin with the css-loader
Then add the loader and the plugin to your webpack config. For example:
style.css
body {
background: green;
} component.js
import './style.css'; webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
}; | Name | Type | Default | Description |
|---|---|---|---|
Name Type Default Description
| {String\|Function} | [name].css | This option determines the name of each output CSS file |
Name Type Default Description
| {String\|Function} | based on filename | This option determines the name of non-entry chunk files |
Name Type Default Description
| {Boolean} | false | Remove Order Warnings |
Name Type Default Description
| {String\|Function} | document.head.appendChild(linkTag); | Inserts <link> at the given position |
Name Type Default Description
| {Object} | {} | Adds custom attributes to tag |
Name Type Default Description
| {String\|Boolean} | text/css | Allows loading asynchronous chunks with a custom link type |
filenameType: String|Function Default: [name].css
This option determines the name of each output CSS file.
Works like output.filename
chunkFilenameType: String|Function Default: based on filename
i Specifying
chunkFilenameas afunctionis only available in webpack@5
This option determines the name of non-entry chunk files.
Works like output.chunkFilename
ignoreOrderType: Boolean Default: false
Remove Order Warnings. See examples below for details.
insertType: String|Function Default: document.head.appendChild(linkTag);
By default, the extract-css-chunks-plugin appends styles (<link> elements) to document.head of the current window.
However in some circumstances it might be necessary to have finer control over the append target or even delay link elements instertion. For example this is the case when you asynchronously load styles for an application that runs inside of an iframe. In such cases insert can be configured to be a function or a custom selector.
If you target an iframe make sure that the parent document has sufficient access rights to reach into the frame document and append elements to it.
StringAllows to setup custom query selector. A new <link> element will be inserted after the found item.
webpack.config.js
new MiniCssExtractPlugin({
insert: '#some-element',
}); A new <link> element will be inserted after the element with id some-element.
FunctionAllows to override default behavior and insert styles at any position.
⚠ Do not forget that this code will run in the browser alongside your application. Since not all browsers support latest ECMA features like
let,const,arrow function expressionand etc we recommend you to use only ECMA 5 features and syntax.
⚠ The
insertfunction is serialized to string and passed to the plugin. This means that it won't have access to the scope of the webpack configuration module.
webpack.config.js
new MiniCssExtractPlugin({
insert: function (linkTag) {
var reference = document.querySelector('#some-element');
if (reference) {
reference.parentNode.insertBefore(linkTag, reference);
}
},
}); A new <link> element will be inserted before the element with id some-element.
attributesType: Object Default: {}
If defined, the mini-css-extract-plugin will attach given attributes with their values on element.
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
attributes: {
id: 'target',
'data-target': 'example',
},
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
}; Note: It's only applied to dynamically loaded css chunks, if you want to modify link attributes inside html file, please using html-webpack-plugin
linkTypeType: String|Boolean Default: text/css
This option allows loading asynchronous chunks with a custom link type, such as <link type="text/css" ...>.
StringPossible values: text/css
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
linkType: 'text/css',
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
}; Booleanfalse disables the link type attribute
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
linkType: false,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
}; | Name | Type | Default | Description |
|---|---|---|---|
Name Type Default Description
| {String\|Function} | webpackOptions.output.publicPath | Specifies a custom public path for the external resources like images, files, etc |
Name Type Default Description
| {Boolean} | true | Use ES modules syntax |
Name Type Default Description
| {Object} | undefined | Configuration CSS Modules |
publicPathType: String|Function Default: the publicPath in webpackOptions.output
Specifies a custom public path for the external resources like images, files, etc inside CSS. Works like output.publicPath
Stringwebpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '/public/path/to/',
},
},
'css-loader',
],
},
],
},
}; Functionwebpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) => {
return path.relative(path.dirname(resourcePath), context) + '/';
},
},
},
'css-loader',
],
},
],
},
}; esModuleType: Boolean Default: true
By default, mini-css-extract-plugin generates JS modules that use the ES modules syntax. There are some cases in which using ES modules is beneficial, like in the case of module concatenation and tree shaking.
You can enable a CommonJS syntax using:
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
esModule: false,
},
},
'css-loader',
],
},
],
},
}; modulesType: Object Default: undefined
Configuration CSS Modules.
namedExportType: Boolean Default: false
Enables/disables ES modules named export for locals.
⚠ Names of locals are converted to
camelCase.
⚠ It is not allowed to use JavaScript reserved words in css class names.
⚠ Options
esModuleandmodules.namedExportincss-loaderandMiniCssExtractPlugin.loadershould be enabled.
styles.css
.foo-baz {
color: red;
}
.bar {
color: blue;
} index.js
import { fooBaz, bar } from './styles.css';
console.log(fooBaz, bar); You can enable a ES module named export using:
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
esModule: true,
modules: {
namedExport: true,
},
},
},
{
loader: 'css-loader',
options: {
esModule: true,
modules: {
namedExport: true,
localIdentName: 'foo__[name]__[local]',
},
},
},
],
},
],
},
}; webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// all options are optional
filename: '[name].css',
chunkFilename: '[id].css',
ignoreOrder: false, // Enable to remove warnings about conflicting order
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
publicPath: '../',
},
},
'css-loader',
],
},
],
},
}; mini-css-extract-plugin is more often used in production mode to get separate css files. For development mode (including webpack-dev-server) you can use style-loader, because it injects CSS into the DOM using multiple
i Do not use together
style-loaderandmini-css-extract-plugin.
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const devMode = process.env.NODE_ENV !== 'production';
const plugins = [];
if (!devMode) {
// enable in production only
plugins.push(new MiniCssExtractPlugin());
}
module.exports = {
plugins,
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader',
],
},
],
},
}; publicPath option as functionwebpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) => {
// publicPath is the relative path of the resource to the context
// e.g. for ./css/admin/main.css the publicPath will be ../../
// while for ./css/main.css the publicPath will be ../
return path.relative(path.dirname(resourcePath), context) + '/';
},
},
},
'css-loader',
],
},
],
},
}; This plugin should not be used with style-loader in the loaders chain.
Here is an example to have both HMR in development and your styles extracted in a file for production builds.
(Loaders options left out for clarity, adapt accordingly to your needs.)
You should not use HotModuleReplacementPlugin plugin if you are using a webpack-dev-server. webpack-dev-server enables / disables HMR using hot option.
webpack.config.js
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const devMode = process.env.NODE_ENV !== 'production';
const plugins = [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? '[name].css' : '[name].[contenthash].css',
chunkFilename: devMode ? '[id].css' : '[id].[contenthash].css',
}),
];
if (devMode) {
// only enable hot in development
plugins.push(new webpack.HotModuleReplacementPlugin());
}
module.exports = {
plugins,
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader',
],
},
],
},
}; Note: HMR is automatically supported in webpack 5. No need to configure it. Skip the following:
The mini-css-extract-plugin supports hot reloading of actual css files in development. Some options are provided to enable HMR of both standard stylesheets and locally scoped CSS or CSS modules. Below is an example configuration of mini-css for HMR use with CSS modules.
You should not use HotModuleReplacementPlugin plugin if you are using a webpack-dev-server. webpack-dev-server enables / disables HMR using hot option.
webpack.config.js
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const plugins = [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? '[name].css' : '[name].[contenthash].css',
chunkFilename: devMode ? '[id].css' : '[id].[contenthash].css',
}),
];
if (devMode) {
// only enable hot in development
plugins.push(new webpack.HotModuleReplacementPlugin());
}
module.exports = {
plugins,
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {},
},
'css-loader',
],
},
],
},
}; To minify the output, use a plugin like css-minimizer-webpack-plugin.
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
optimization: {
minimizer: [
// For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
// `...`
new CssMinimizerPlugin(),
],
},
}; This will enable CSS optimization only in production mode. If you want to run it also in development set the optimization.minimize option to true.
The runtime code detects already added CSS via <link> or <style> tag. This can be useful when injecting CSS on server-side for Server-Side-Rendering. The href of the <link> tag has to match the URL that will be used for loading the CSS chunk. The data-href attribute can be used for <link> and <style> too. When inlining CSS data-href must be used.
The CSS can be extracted in one CSS file using optimization.splitChunks.cacheGroups.
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true,
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
}; You may also extract the CSS based on the webpack entry name. This is especially useful if you import routes dynamically but want to keep your CSS bundled according to entry. This also prevents the CSS duplication issue one had with the ExtractTextPlugin.
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
function recursiveIssuer(m, c) {
const issuer = c.moduleGraph.getIssuer(m);
// For webpack@4 chunks = m.issuer
if (issuer) {
return recursiveIssuer(issuer, c);
}
const chunks = c.chunkGraph.getModuleChunks(m);
// For webpack@4 chunks = m._chunks
for (const chunk of chunks) {
return chunk.name;
}
return false;
}
module.exports = {
entry: {
foo: path.resolve(__dirname, 'src/foo'),
bar: path.resolve(__dirname, 'src/bar'),
},
optimization: {
splitChunks: {
cacheGroups: {
fooStyles: {
name: 'styles_foo',
test: (m, c, entry = 'foo') =>
m.constructor.name === 'CssModule' &&
recursiveIssuer(m, c) === entry,
chunks: 'all',
enforce: true,
},
barStyles: {
name: 'styles_bar',
test: (m, c, entry = 'bar') =>
m.constructor.name === 'CssModule' &&
recursiveIssuer(m, c) === entry,
chunks: 'all',
enforce: true,
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
}; With the filename option you can use chunk data to customize the filename. This is particularly useful when dealing with multiple entry points and wanting to get more control out of the filename for a given entry point/chunk. In the example below, we'll use filename to output the generated css into a different directory.
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: ({ chunk }) => `${chunk.name.replace('/js/', '/css/')}.css`,
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
}; For long term caching use filename: "[contenthash].css". Optionally add [name].
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
chunkFilename: '[id].[contenthash].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
}; For projects where css ordering has been mitigated through consistent use of scoping or naming conventions, the css order warnings can be disabled by setting the ignoreOrder flag to true for the plugin.
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
ignoreOrder: true,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
}; If you'd like to extract the media queries from the extracted CSS (so mobile users don't need to load desktop or tablet specific CSS anymore) you should use one of the following plugins:
Please take a moment to read our contributing guidelines if you haven't yet done so.
In the past, one of webpack’s trade-offs when bundling was that each module in your bundle would be wrapped in individual function closures. These wrapper functions made it slower for your JavaScript to execute in the browser. In comparison, tools like Closure Compiler and RollupJS ‘hoist’ or concatenate the scope of all your modules into one closure and allow for your code to have a faster execution time in the browser.
This plugin will enable the same concatenation behavior in webpack. By default this plugin is already enabled in production mode and disabled otherwise. If you need to override the production mode optimization, set the optimization.concatenateModules option to false. To enable concatenation behavior in other modes, you can add ModuleConcatenationPlugin manually or use the optimization.concatenateModules option:
new webpack.optimize.ModuleConcatenationPlugin(); This concatenation behavior is called “scope hoisting.”
Scope hoisting is specifically a feature made possible by ECMAScript Module syntax. Because of this webpack may fallback to normal bundling based on what kind of modules you are using, and other conditions.
Keep in mind that this plugin will only be applied to ES6 modules processed directly by webpack. When using a transpiler, you'll need to disable module processing (e.g. the
modulesoption in Babel).
As the article explains, webpack attempts to achieve partial scope hoisting. It will merge modules into a single scope but cannot do so in every case. If webpack cannot merge a module, the two alternatives are Prevent and Root. Prevent means the module must be in its own scope. Root means a new module group will be created. The following conditions determine the outcome:
| Condition | Outcome |
|---|---|
Condition Outcome Non ES6 Module Prevent | Prevent |
Condition Outcome Imported By Non Import Root | Root |
Condition Outcome Imported From Other Chunk Root | Root |
Condition Outcome Imported By Multiple Other Module Groups Root | Root |
Condition Outcome Imported With Root | Root |
Condition Outcome Affected By Prevent | Prevent |
Condition Outcome HMR Accepted Root | Root |
Condition Outcome Using Prevent | Prevent |
Condition Outcome In Multiple Chunks Prevent | Prevent |
Condition Outcome
Prevent | Prevent |
The following pseudo JavaScript explains the algorithm:
modules.forEach(module => {
const group = new ModuleGroup({
root: module
});
module.dependencies.forEach(dependency => {
tryToAdd(group, dependency);
});
if (group.modules.length > 1) {
orderedModules = topologicalSort(group.modules);
concatenatedModule = new ConcatenatedModule(orderedModules);
chunk.add(concatenatedModule);
orderedModules.forEach(groupModule => {
chunk.remove(groupModule);
});
}
});
function tryToAdd(group, module) {
if (group.has(module)) {
return true;
}
if (!hasPreconditions(module)) {
return false;
}
const nextGroup = group;
const result = module.dependents.reduce((check, dependent) => {
return check && tryToAdd(nextGroup, dependent);
}, true);
if (!result) {
return false;
}
module.dependencies.forEach(dependency => {
tryToAdd(group, dependency);
});
group.merge(nextGroup);
return true;
} When using the webpack CLI, the --display-optimization-bailout flag will display bailout reasons. When using the webpack config, just add the following to the stats object:
module.exports = {
//...
stats: {
// Examine all modules
maxModules: Infinity,
// Display bailout reasons
optimizationBailout: true
}
}; webpack has a rich plugin interface. Most of the features within webpack itself use this plugin interface. This makes webpack flexible.
| Name | Description |
|---|---|
Name Description Add a banner to the top of each generated chunk | Add a banner to the top of each generated chunk |
Name Description Extract common modules shared between chunks | Extract common modules shared between chunks |
Name Description Prepare compressed versions of assets to serve them with Content-Encoding | Prepare compressed versions of assets to serve them with Content-Encoding |
Name Description Override the inferred context of a | Override the inferred context of a require expression |
Name Description Copies individual files or entire directories to the build directory | Copies individual files or entire directories to the build directory |
Name Description Allow global constants configured at compile time | Allow global constants configured at compile time |
Name Description Split bundles in order to drastically improve build time | Split bundles in order to drastically improve build time |
Name Description Shorthand for using the | Shorthand for using the DefinePlugin on process.env keys |
Name Description A ESLint plugin for webpack | A ESLint plugin for webpack |
Name Description Enable Hot Module Replacement (HMR) | Enable Hot Module Replacement (HMR) |
Name Description Easily create HTML files to serve your bundles | Easily create HTML files to serve your bundles |
Name Description Exclude certain modules from bundles | Exclude certain modules from bundles |
Name Description Set min/max limits for chunking to better control chunking | Set min/max limits for chunking to better control chunking |
Name Description Keep chunk size above the specified limit | Keep chunk size above the specified limit |
Name Description creates a CSS file per JS file which requires CSS | creates a CSS file per JS file which requires CSS |
Name Description Skip the emitting phase when there are compilation errors | Skip the emitting phase when there are compilation errors |
Name Description Replace resource(s) that matches a regexp | Replace resource(s) that matches a regexp |
Name Description Auto-install missing dependencies during development | Auto-install missing dependencies during development |
Name Description Report compilation progress | Report compilation progress |
Name Description Use modules without having to use import/require | Use modules without having to use import/require |
Name Description Enables a more fine grained control of source maps | Enables a more fine grained control of source maps |
Name Description Enables a more fine grained control of eval source maps | Enables a more fine grained control of eval source maps |
Name Description Uses Terser to minify the JS in your project | Uses Terser to minify the JS in your project |
For more third-party plugins, see the list from awesome-webpack.
The NoEmitOnErrorsPlugin allows you to avoid emitting assets when there are any errors. Enabled by default, you can disable using optimization.emitOnErrors
webpack.config.js
module.exports = {
plugins: [
new webpack.NoEmitOnErrorsPlugin()
]
};
The NormalModuleReplacementPlugin allows you to replace resources that match resourceRegExp with newResource. If newResource is relative, it is resolved relative to the previous resource. If newResource is a function, it is expected to overwrite the request attribute of the supplied resource.
This can be useful for allowing different behaviour between builds.
new webpack.NormalModuleReplacementPlugin(
resourceRegExp,
newResource
); Replace a specific module when building for a development environment.
Say you have a configuration file some/path/config.development.module.js and a special version for production in some/path/config.production.module.js
Just add the following plugin when building for production:
new webpack.NormalModuleReplacementPlugin(
/some\/path\/config\.development\.js/,
'./config.production.js'
); Conditional build depending on an specified environment.
Say you want a configuration with specific values for different build targets.
module.exports = function(env) {
var appTarget = env.APP_TARGET || 'VERSION_A';
return {
plugins: [
new webpack.NormalModuleReplacementPlugin(/(.*)-APP_TARGET(\.*)/, function(resource) {
resource.request = resource.request.replace(/-APP_TARGET/, `-${appTarget}`);
})
]
};
}; Create the two configuration files:
app/config-VERSION_A.js
export default {
title : 'I am version A'
}; app/config-VERSION_B.js
export default {
title : 'I am version B'
}; Then import that configuration using the keyword you're looking for in the regexp:
import config from 'app/config-APP_TARGET';
console.log(config.title); And now you just get the right configuration imported depending on which target you're building for:
webpack --env.APP_TARGET VERSION_A
=> 'I am version A'
webpack --env.APP_TARGET VERSION_B
=> 'I am version B' Speed up development by automatically installing & saving dependencies with Webpack.
It is inefficient to Ctrl-C your build script & server just to install a dependency you didn't know you needed until now.
Instead, use require or import how you normally would and npm install will happen automatically to install & save missing dependencies while you work!
$ npm install --save-dev npm-install-webpack-plugin In your webpack.config.js:
plugins: [
new NpmInstallPlugin()
], This is equivalent to:
plugins: [
new NpmInstallPlugin({
// Use --save or --save-dev
dev: false,
// Install missing peerDependencies
peerDependencies: true,
// Reduce amount of console logging
quiet: false,
// npm command used inside company, yarn is not supported yet
npm: 'npm'
});
], You can provide a Function to the dev to make it dynamic:
plugins: [
new NpmInstallPlugin({
dev: function(module, path) {
return [
"babel-preset-react-hmre",
"webpack-dev-middleware",
"webpack-hot-middleware",
].indexOf(module) !== -1;
},
}),
], 
^v1.12.0 and ^2.1.0-beta.0..babelrc plugins & presets.require, import)@cycle/dom)lodash.capitalize)@import "~bootstrap")babel-loader, file-loader, etc.)require("bundle?lazy!./App")peerDependencies. (e.g. @cycle/core will automatically install rx@*)resolve.alias & resolve.root configuration. (e.g. require("react") can alias to react-lite)Please take a moment to read our contributing guidelines if you haven't yet done so.
| Eric Clemmons | Jonny Buchanan |
Prefetch normal module requests, causing them to be resolved and built before the first import or require of that module occurs. Using this plugin can boost performance. Try to profile the build first to determine clever prefetching points.
new webpack.PrefetchPlugin([context], request); context: An absolute path to a directoryrequest: A request string for a normal moduleGenerate Chrome profile file which includes timings of plugins execution. Outputs events.json file by default. It is possible to provide custom file path using outputPath option.
Note : ProfilingPlugin accepts only absolute paths.
outputPath: An absolute path to a custom output file (json)new webpack.debug.ProfilingPlugin(); outputPathnew webpack.debug.ProfilingPlugin({
outputPath: 'profiling/profileEvents.json'
}); In order to view the profile file:
ProfilingPlugin.Performance tab (formerly Timeline).events.json by default) into the profiler.It will then display timeline stats and calls per plugin!
object = { boolean activeModules = true, boolean entries = false, function (number percentage, string message, [string] ...args) handler, boolean modules = true, number modulesCount = 500, boolean profile = false }
function (number percentage, string message, [string] ...args)
The ProgressPlugin provides a way to customize how progress is reported during a compilation.
Create an instance of ProgressPlugin and provide one of the allowed params.
functionProvide a handler function which will be called when hooks report progress. handler function arguments:
percentage: a number between 0 and 1 indicating the completion percentage of the compilationmessage: a short description of the currently-executing hook...args: zero or more additional strings describing the current progressconst handler = (percentage, message, ...args) => {
// e.g. Output each progress message directly to the console:
console.info(percentage, message, ...args);
};
new webpack.ProgressPlugin(handler); objectWhen providing an object to the ProgressPlugin, following properties are supported:
activeModules (boolean = false): Shows active modules count and one active module in progress message.entries (boolean = true): Shows entries count in progress message.handler (See Providing function)modules (boolean = true): Shows modules count in progress message.modulesCount (number = 5000): A minimum modules count to start with. Takes effect when modules property is enabled.profile (boolean = false): Tells ProgressPlugin to collect profile data for progress steps.dependencies (boolean = true): Shows the count of dependencies in progress message.dependenciesCount (number = 10000): A minimum dependencies count to start with. Takes effect when dependencies property is enabled.percentBy (string = null: 'entries' | 'dependencies' | 'modules' | null): Tells ProgressPlugin how to calculate progress percentage.new webpack.ProgressPlugin({
activeModules: false,
entries: true,
handler(percentage, message, ...args) {
// custom logic
},
modules: true,
modulesCount: 5000,
profile: false,
dependencies: true,
dependenciesCount: 10000,
percentBy: null
}); By default, progress percentage is calculated based on built modules count and total modules count: built / total
The total modules count is unknown in advance and changes during the build. This may cause inaccurate progress percentage.
To solve this problem ProgressPlugin caches the last known total modules count and reuses this value on the next build. The first build will warm the cache but the following builds will use and update this value.
We recommend using
percentBy: 'entries'setting for projects with multiple configured entry points. Percentage calculation will become more accurate because the amount of entry points is known in advance.
The following hooks report progress information to ProgressPlugin.
Hooks marked with * allow plugins to report progress information using
reportProgress. For more, see Plugin API: Reporting Progress
Compiler
Compilation
Automatically load modules instead of having to import or require them everywhere.
new webpack.ProvidePlugin({
identifier: 'module1',
// ...
}); or
new webpack.ProvidePlugin({
identifier: ['module1', 'property1'],
// ...
}); By default, module resolution path is current folder (./**) and node_modules.
It is also possible to specify full path:
const path = require('path');
new webpack.ProvidePlugin({
identifier: path.resolve(path.join(__dirname, 'src/module1'))
// ...
}); Whenever the identifier is encountered as free variable in a module, the module is loaded automatically and the identifier is filled with the exports of the loaded module (or property in order to support named exports).
For importing the default export of an ES2015 module, you have to specify the default property of module.
To automatically load jquery we can simply point both variables it exposes to the corresponding node module:
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}); Then in any of our source code:
// in a module
$('#item'); // <= just works
jQuery('#item'); // <= just works
// $ is automatically set to the exports of module "jquery" Angular looks for window.jQuery in order to determine whether jQuery is present, see the source code.
new webpack.ProvidePlugin({
'window.jQuery': 'jquery'
}); new webpack.ProvidePlugin({
_map: ['lodash', 'map']
}); new webpack.ProvidePlugin({
Vue: ['vue/dist/vue.esm.js', 'default']
}); This plugin enables more fine grained control of source map generation. It is also enabled automatically by certain settings of the devtool configuration option.
new webpack.SourceMapDevToolPlugin(options); The following options are supported:
test (string RegExp [string, RegExp]): Include source maps for modules based on their extension (defaults to .js, .mjs, and .css).include (string RegExp [string, RegExp]): Include source maps for module paths that match the given value.exclude (string RegExp [string, RegExp]): Exclude modules that match the given value from source map generation.filename (string): Defines the output filename of the SourceMap (will be inlined if no value is provided).append (string): Appends the given value to the original asset. Usually the #sourceMappingURL comment. [url] is replaced with a URL to the source map file. Since webpack v4.36.0, path parameters are supported: [chunk], [filename] and [contenthash]. Setting append to false disables the appending.moduleFilenameTemplate (string): See output.devtoolModuleFilenameTemplate.fallbackModuleFilenameTemplate (string): See link above.namespace (string): See output.devtoolNamespace.module = true (boolean): Indicates whether loaders should generate source maps.columns = true (boolean): Indicates whether column mappings should be used.noSources = false (boolean): Prevents the source file content from being included in the source map.publicPath (string): Emits absolute URLs with public path prefix, e.g. https://example.com/project/.fileContext (string): Makes the [file] argument relative to this directory.sourceRoot (string): Provide a custom value for the sourceRoot property in the SourceMap.The fileContext option is useful when you want to store source maps in an upper level directory to avoid ../../ appearing in the absolute [url].
Setting
moduleand/orcolumnstofalsewill yield less accurate source maps but will also improve compilation performance significantly.
If you want to use a custom configuration for this plugin in development mode, make sure to disable the default one. I.e. set
devtool: false.
If the default webpack
minimizerhas been overridden (such as to customise theTerserPluginoptions), make sure to configure its replacement withsourceMap: trueto enable SourceMap support.
The following examples demonstrate some common use cases for this plugin.
You can use the following code to replace the configuration option devtool: inline-source-map with an equivalent custom plugin configuration:
module.exports = {
// ...
devtool: false,
plugins: [
new webpack.SourceMapDevToolPlugin({})
]
}; The following code would exclude source maps for any modules in the vendor.js bundle:
new webpack.SourceMapDevToolPlugin({
filename: '[name].js.map',
exclude: ['vendor.js']
}); Set a URL for source maps. Useful for hosting them on a host that requires authorization.
new webpack.SourceMapDevToolPlugin({
append: '\n//# sourceMappingURL=https://example.com/sourcemap/[url]',
filename: '[name].map'
}); And for cases when source maps are stored in the upper level directory:
project
|- dist
|- public
|- bundle-[hash].js
|- sourcemaps
|- bundle-[hash].js.map
With next config:
new webpack.SourceMapDevToolPlugin({
filename: 'sourcemaps/[file].map',
publicPath: 'https://example.com/project/',
fileContext: 'public'
}); Will produce the following URL:
https://example.com/project/sourcemaps/bundle-[hash].js.map
Originally, chunks (and modules imported inside them) were connected by a parent-child relationship in the internal webpack graph. The CommonsChunkPlugin was used to avoid duplicated dependencies across them, but further optimizations were not possible.
Since webpack v4, the CommonsChunkPlugin was removed in favor of optimization.splitChunks.
Out of the box SplitChunksPlugin should work well for most users.
By default it only affects on-demand chunks, because changing initial chunks would affect the script tags the HTML file should include to run the project.
webpack will automatically split chunks based on these conditions:
node_modules folderWhen trying to fulfill the last two conditions, bigger chunks are preferred.
webpack provides a set of options for developers that want more control over this functionality.
The default configuration was chosen to fit web performance best practices, but the optimal strategy for your project might differ. If you're changing the configuration, you should measure the impact of your changes to ensure there's a real benefit.
optimization.splitChunksThis configuration object represents the default behavior of the SplitChunksPlugin.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
chunks: 'async',
minSize: 20000,
minRemainingSize: 0,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 30,
maxInitialRequests: 30,
automaticNameDelimiter: '~',
enforceSizeThreshold: 50000,
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
}; When files paths are processed by webpack, they always contain
/on Unix systems and\on Windows. That's why using[\\/]in{cacheGroup}.testfields is necessary to represent a path separator./or\in{cacheGroup}.testwill cause issues when used cross-platform.
Since webpack 5, passing an entry name to
{cacheGroup}.testand using a name of an existing chunk for{cacheGroup}.nameis no longer allowed.
splitChunks.automaticNameDelimiterstring = '~'
By default webpack will generate names using origin and name of the chunk (e.g. vendors~main.js). This option lets you specify the delimiter to use for the generated names.
splitChunks.chunksstring = 'async' function (chunk)
This indicates which chunks will be selected for optimization. When a string is provided, valid values are all, async, and initial. Providing all can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
// include all types of chunks
chunks: 'all'
}
}
}; Alternatively, you may provide a function for more control. The return value will indicate whether to include each chunk.
module.exports = {
//...
optimization: {
splitChunks: {
chunks (chunk) {
// exclude `my-excluded-chunk`
return chunk.name !== 'my-excluded-chunk';
}
}
}
}; You can combine this configuration with the HtmlWebpackPlugin. It will inject all the generated vendor chunks for you.
splitChunks.maxAsyncRequestsnumber = 30
Maximum number of parallel requests when on-demand loading.
splitChunks.maxInitialRequestsnumber = 30
Maximum number of parallel requests at an entry point.
splitChunks.minChunksnumber = 1
Minimum number of chunks that must share a module before splitting.
splitChunks.minSizenumber = 20000
Minimum size, in bytes, for a chunk to be generated.
splitChunks.enforceSizeThresholdsplitChunks.cacheGroups.{cacheGroup}.enforceSizeThresholdnumber = 50000
Size threshold at which splitting is enforced and other restrictions (minRemainingSize, maxAsyncRequests, maxInitialRequests) are ignored.
splitChunks.minRemainingSizesplitChunks.cacheGroups.{cacheGroup}.minRemainingSizenumber = 0
splitChunks.minRemainingSize option was introduced in webpack 5 to avoid zero sized modules by ensuring that the minimum size of the chunk which remains after splitting is above a limit. Defaults to 0 in 'development' mode. For other cases splitChunks.minRemainingSize defaults to the value of splitChunks.minSize so it doesn't need to be specified manually except for the rare cases where deep control is required.
splitChunks.minRemainingSizeonly takes effect when a single chunk is remaining.
splitChunks.maxSizenumber = 0
Using maxSize (either globally optimization.splitChunks.maxSize per cache group optimization.splitChunks.cacheGroups[x].maxSize or for the fallback cache group optimization.splitChunks.fallbackCacheGroup.maxSize) tells webpack to try to split chunks bigger than maxSize bytes into smaller parts. Parts will be at least minSize (next to maxSize) in size. The algorithm is deterministic and changes to the modules will only have local impact. So that it is usable when using long term caching and doesn't require records. maxSize is only a hint and could be violated when modules are bigger than maxSize or splitting would violate minSize.
When the chunk has a name already, each part will get a new name derived from that name. Depending on the value of optimization.splitChunks.hidePathInfo it will add a key derived from the first module name or a hash of it.
maxSize option is intended to be used with HTTP/2 and long term caching. It increases the request count for better caching. It could also be used to decrease the file size for faster rebuilding.
maxSizetakes higher priority thanmaxInitialRequest/maxAsyncRequests. Actual priority ismaxInitialRequest/maxAsyncRequests < maxSize < minSize.
Setting the value for
maxSizesets the value for bothmaxAsyncSizeandmaxInitialSize.
splitChunks.maxAsyncSizenumber
Like maxSize, maxAsyncSize can be applied globally (splitChunks.maxAsyncSize), to cacheGroups (splitChunks.cacheGroups.{cacheGroup}.maxAsyncSize), or to the fallback cache group (splitChunks.fallbackCacheGroup.maxAsyncSize).
The difference between maxAsyncSize and maxSize is that maxAsyncSize will only affect on-demand loading chunks.
splitChunks.maxInitialSizenumber
Like maxSize, maxInitialSize can be applied globally (splitChunks.maxInitialSize), to cacheGroups (splitChunks.cacheGroups.{cacheGroup}.maxInitialSize), or to the fallback cache group (splitChunks.fallbackCacheGroup.maxInitialSize).
The difference between maxInitialSize and maxSize is that maxInitialSize will only affect initial load chunks.
splitChunks.nameboolean = false function (module, chunks, cacheGroupKey) => string string
Also available for each cacheGroup: splitChunks.cacheGroups.{cacheGroup}.name.
The name of the split chunk. Providing false will keep the same name of the chunks so it doesn't change names unnecessarily. It is the recommended value for production builds.
Providing a string or a function allows you to use a custom name. Specifying either a string or a function that always returns the same string will merge all common modules and vendors into a single chunk. This might lead to bigger initial downloads and slow down page loads.
If you choose to specify a function, you may find the chunk.name and chunk.hash properties (where chunk is an element of the chunks array) particularly useful in choosing a name for your chunk.
If the splitChunks.name matches an entry point name, the entry point will be removed.
main.js
import _ from 'lodash';
console.log(_.join(['Hello', 'webpack'], ' ')); webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
// cacheGroupKey here is `commons` as the key of the cacheGroup
name(module, chunks, cacheGroupKey) {
const moduleFileName = module.identifier().split('/').reduceRight(item => item);
const allChunksNames = chunks.map((item) => item.name).join('~');
return `${cacheGroupKey}-${allChunksNames}-${moduleFileName}`;
},
chunks: 'all'
}
}
}
}
}; Running webpack with following splitChunks configuration would also output a chunk of the group common with next name: commons-main-lodash.js.e7519d2bb8777058fa27.js (hash given as an example of real world output).
When assigning equal names to different split chunks, all vendor modules are placed into a single shared chunk, though it's not recommend since it can result in more code downloaded.
splitChunks.automaticNamePrefixstring = ''
Sets the name prefix for created chunks.
module.exports = {
//...
optimization: {
splitChunks: {
automaticNamePrefix: 'general-prefix',
cacheGroups: {
react: {
// ...
automaticNamePrefix: 'react-chunks-prefix'
}
}
}
}
}; splitChunks.usedExportssplitChunks.cacheGroups{cacheGroup}.usedExportsboolean = true
Figure out which exports are used by modules to mangle export names, omit unused exports and generate more efficient code. When it is true: analyse used exports for each runtime, when it is "global": analyse exports globally for all runtimes combined).
splitChunks.cacheGroupsCache groups can inherit and/or override any options from splitChunks.*; but test, priority and reuseExistingChunk can only be configured on cache group level. To disable any of the default cache groups, set them to false.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
default: false
}
}
}
}; splitChunks.cacheGroups.{cacheGroup}.prioritynumber
A module can belong to multiple cache groups. The optimization will prefer the cache group with a higher priority. The default groups have a negative priority to allow custom groups to take higher priority (default value is 0 for custom groups).
splitChunks.cacheGroups.{cacheGroup}.reuseExistingChunkboolean
If the current chunk contains modules already split out from the main bundle, it will be reused instead of a new one being generated. This can impact the resulting file name of the chunk.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
reuseExistingChunk: true
}
}
}
}
}; splitChunks.cacheGroups.{cacheGroup}.typefunction RegExp string
Allows to assign modules to a cache group by module type.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
json: {
type: 'json'
}
}
}
}
}; splitChunks.cacheGroups.testsplitChunks.cacheGroups.{cacheGroup}.testfunction (module, chunk) => boolean RegExp string
Controls which modules are selected by this cache group. Omitting it selects all modules. It can match the absolute module resource path or chunk names. When a chunk name is matched, all modules in the chunk are selected.
Providing a function to{cacheGroup}.test:
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
svgGroup: {
test(module, chunks) {
// `module.resource` contains the absolute path of the file on disk.
// Note the usage of `path.sep` instead of / or \, for cross-platform compatibility.
const path = require('path');
return module.resource &&
module.resource.endsWith('.svg') &&
module.resource.includes(`${path.sep}cacheable_svgs${path.sep}`);
}
},
byModuleTypeGroup: {
test(module, chunks) {
return module.type === 'javascript/auto';
}
}
}
}
}
}; In order to see what information is available in module and chunks objects, you can put debugger; statement in the callback. Then run your webpack build in debug mode to inspect the parameters in Chromium DevTools.
Providing a RegExp to {cacheGroup}.test:
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
// Note the usage of `[\\/]` as a path separator for cross-platform compatibility.
test: /[\\/]node_modules[\\/]|vendor[\\/]analytics_provider|vendor[\\/]other_lib/
}
}
}
}
}; splitChunks.cacheGroups.{cacheGroup}.filenamestring function (pathData, assetInfo) => string
Allows to override the filename when and only when it's an initial chunk. All placeholders available in output.filename are also available here.
This option can also be set globally in
splitChunks.filename, but this isn't recommended and will likely lead to an error ifsplitChunks.chunksis not set to'initial'. Avoid setting it globally.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
filename: '[name].bundle.js'
}
}
}
}
}; And as a function:
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
filename: (pathData) => {
// Use pathData object for generating filename string based on your requirements
return `${pathData.chunk.name}-bundle.js`;
}
}
}
}
}
}; It is possible to create a folder structure by providing path prefixing the filename: 'js/vendor/bundle.js'.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
filename: 'js/[name]/bundle.js'
}
}
}
}
}; splitChunks.cacheGroups.{cacheGroup}.enforceboolean = false
Tells webpack to ignore splitChunks.minSize, splitChunks.minChunks, splitChunks.maxAsyncRequests and splitChunks.maxInitialRequests options and always create chunks for this cache group.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
enforce: true
}
}
}
}
}; splitChunks.cacheGroups.{cacheGroup}.idHintstring
Sets the hint for chunk id. It will be added to chunk's filename.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
idHint: 'vendors'
}
}
}
}
}; // index.js
import('./a'); // dynamic import // a.js
import 'react';
//... Result: A separate chunk would be created containing react. At the import call this chunk is loaded in parallel to the original chunk containing ./a.
Why:
node_modulesreact is bigger than 30kbWhat's the reasoning behind this? react probably won't change as often as your application code. By moving it into a separate chunk this chunk can be cached separately from your app code (assuming you are using chunkhash, records, Cache-Control or other long term cache approach).
// entry.js
// dynamic imports
import('./a');
import('./b'); // a.js
import './helpers'; // helpers is 40kb in size
//... // b.js
import './helpers';
import './more-helpers'; // more-helpers is also 40kb in size
//... Result: A separate chunk would be created containing ./helpers and all dependencies of it. At the import calls this chunk is loaded in parallel to the original chunks.
Why:
helpers is bigger than 30kbPutting the content of helpers into each chunk will result into its code being downloaded twice. By using a separate chunk this will only happen once. We pay the cost of an additional request, which could be considered a tradeoff. That's why there is a minimum size of 30kb.
Create a commons chunk, which includes all code shared between entry points.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
commons: {
name: 'commons',
chunks: 'initial',
minChunks: 2
}
}
}
}
}; This configuration can enlarge your initial bundles, it is recommended to use dynamic imports when a module is not immediately needed.
Create a vendors chunk, which includes all code from node_modules in the whole application.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
}; This might result in a large chunk containing all external packages. It is recommended to only include your core frameworks and utilities and dynamically load the rest of the dependencies.
Create a custom vendor chunk, which contains certain node_modules packages matched by RegExp.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
name: 'vendor',
chunks: 'all',
}
}
}
}
}; This will result in splitting
reactandreact-dominto a separate chunk. If you're not sure what packages have been included in a chunk you may refer to Bundle Analysis section for details.
A Stylelint plugin for webpack
npm install stylelint-webpack-plugin --save-dev Note: You also need to install stylelint from npm, if you haven't already:
npm install stylelint --save-dev In your webpack configuration:
const StylelintPlugin = require('stylelint-webpack-plugin');
module.exports = {
// ...
plugins: [new StylelintPlugin(options)],
// ...
}; See stylelint's options for the complete list of options available. These options are passed through to the stylelint directly.
configFileStringundefinedSpecify the config file location to be used by stylelint.
Note: By default this is handled by stylelint.
contextStringcompiler.contextA string indicating the root of your files.
filesString|Array[String]'**/*.s?(a|c)ss'Specify the glob pattern for finding files. Must be relative to options.context.
fixBooleanfalseIf true, stylelint will fix as many errors as possible. The fixes are made to the actual source files. All unfixed errors will be reported. See Autofixing errors docs.
formatterString|Function'string'Specify the formatter that you would like to use to format your results. See formatter option.
lintDirtyModulesOnlyBooleanfalseLint only changed files, skip lint on start.
stylelintPathStringstylelintPath to stylelint instance that will be used for linting.
By default the plugin will auto adjust error reporting depending on stylelint errors/warnings counts. You can still force this behavior by using emitError or emitWarning options:
emitErrorBooleanfalseWill always return errors, if set to true.
emitWarningBooleanfalseWill always return warnings, if set to true.
failOnErrorBooleanfalseWill cause the module build to fail if there are any errors, if set to true.
failOnWarningBooleanfalseWill cause the module build to fail if there are any warnings, if set to true.
quietBooleanfalseWill process and report errors only and ignore warnings, if set to true.
This plugin uses terser to minify your JavaScript.
If you are using webpack v5 or above you do not need to install this plugin. Webpack v5 comes with the latest terser-webpack-plugin out of the box.
To begin, you'll need to install terser-webpack-plugin:
$ npm install terser-webpack-plugin --save-dev
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.
Works only with source-map, inline-source-map, hidden-source-map and nosources-source-map values for the devtool option.
Why?
eval wraps modules in eval("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.
testType: 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,
}),
],
},
}; includeType: String|RegExp|Array<String|RegExp> Default: undefined
Files to include.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
include: /\/includes/,
}),
],
},
}; excludeType: String|RegExp|Array<String|RegExp> Default: undefined
Files to exclude.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
exclude: /\/excludes/,
}),
],
},
}; parallelType: Boolean|Number Default: true
Use multi-process parallel running to improve the build speed. Default number of concurrent runs: os.cpus().length - 1.
ℹ️ Parallelization can speedup your build significantly and is therefore highly recommended.
⚠️ 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).
BooleanEnable/disable multi-process parallel running.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
}; NumberEnable multi-process parallel running and set number of concurrent runs.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: 4,
}),
],
},
}; minifyType: Function Default: undefined
Allows you to override default minify function. By default plugin uses terser package. Useful for using and testing unpublished versions or forks.
⚠️ Always use
requireinsideminifyfunction whenparalleloption enabled.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
myCustomOption: true,
},
// Can be async
minify: (file, sourceMap, minimizerOptions) => {
// The `minimizerOptions` option contains option from the `terserOptions` option
// You can use `minimizerOptions.myCustomOption`
const extractedComments = [];
// Custom logic for extract comments
const { map, code } = require('uglify-module') // Or require('./path/to/uglify-module')
.minify(file, {
/* Your options for minification */
});
return { map, code, extractedComments };
},
}),
],
},
}; terserOptionsType: Object Default: default
Terser minify 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,
},
}),
],
},
}; extractCommentsType: Boolean|String|RegExp|Function<(node, comment) -> Boolean|Object>|Object 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.
BooleanEnable/disable extracting comments.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
}),
],
},
}; StringExtract all or some (use /^\**!|@preserve|@license|@cc_on/i RegExp) comments.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: 'all',
}),
],
},
}; RegExpAll 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<(node, comment) -> Boolean>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;
},
}),
],
},
}; ObjectAllow 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}`;
},
},
}),
],
},
}; conditionType: Boolean|String|RegExp|Function<(node, comment) -> Boolean|Object>
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}`;
},
},
}),
],
},
}; filenameType: String|Function<(string) -> String> 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.
⚠️ We highly recommend using the
txtextension. Usingjs/cjs/mjsextensions 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}`;
},
},
}),
],
},
}; bannerType: Boolean|String|Function<(string) -> String> 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}`;
},
},
}),
],
},
}; 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,
}),
],
},
}; 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,
}),
],
},
}; 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);
},
}),
],
},
}; Please take a moment to read our contributing guidelines if you haven't yet done so.
Ignore the specified files, i.e. those matching the provided paths or regular expressions, while in watch mode.
new webpack.WatchIgnorePlugin(paths); paths ([string, RegExp]): A list of RegExps or absolute paths to directories or files that should be ignored