AutomaticPrefetchPlugin
会观察之前编译的 所有模块 的变化,以改进增量构建的时间。对比PrefetchPlugin
而言,PrefetchPlugin
是预先发现 单个模块。
webpack.config.js
module.exports = {
// ...
plugins: [new webpack.AutomaticPrefetchPlugin()],
};
为每个 chunk 文件头部添加 banner。
const webpack = require('webpack');
new webpack.BannerPlugin(banner);
// 或者
new webpack.BannerPlugin(options);
{
banner: string | function, // 其值为字符串或函数,将作为注释存在
raw: boolean, // 如果值为 true,将直接输出,不会被作为注释
entryOnly: boolean, // 如果值为 true,将只在入口 chunks 文件中添加
test: string | RegExp | [string, RegExp], // 包含所有匹配的模块
include: string | RegExp | [string, RegExp], // 根据条件匹配所有模块
exclude: string | RegExp | [string, RegExp], // 根据条件排除所有模块
footer?: boolean, // 如果值为 true,banner 将会位于编译结果的最下方
}
import webpack from 'webpack';
// 字符串
new webpack.BannerPlugin({
banner: 'hello world',
});
// 函数
new webpack.BannerPlugin({
banner: (yourVariable) => {
return `yourVariable: ${yourVariable}`;
},
});
从 webpack 2.5.0 开始,会对 banner
字符串中的占位符取值:
import webpack from 'webpack';
new webpack.BannerPlugin({
banner:
'fullhash:[fullhash], chunkhash:[chunkhash], name:[name], filebase:[filebase], query:[query], file:[file]',
});
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.
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` 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>
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 |
---|---|---|---|
test | {String|RegExp|Array<String|RegExp>} | undefined | Include all assets that pass test assertion |
include | {String|RegExp|Array<String|RegExp>} | undefined | Include all assets matching any of these conditions |
exclude | {String|RegExp|Array<String|RegExp>} | undefined | Exclude all assets matching any of these conditions |
algorithm | {String|Function} | gzip | The compression algorithm/function |
compressionOptions | {Object} | maximum available compression level, for gzip: { level: 9 } | Compression options for algorithm |
threshold | {Number} | 0 | Only assets bigger than this size are processed (in bytes) |
minRatio | {Number} | 0.8 | Only assets that compress better than this ratio are processed (minRatio = Compressed Size / Original Size ) |
filename | {String|Function} | [path][base].gz | The target asset filename |
deleteOriginalAssets | {Boolean|'keep-source-map'} | false | Whether to delete the original assets or not |
test
Type: 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,
}),
],
};
include
Type: 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/,
}),
],
};
exclude
Type: 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/,
}),
],
};
algorithm
Type: String|Function
Default: gzip
The compression algorithm/function.
ℹ️ If you use custom function for the
algorithm
option, the default value of thecompressionOptions
option is{}
.
String
The algorithm is taken from zlib.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
algorithm: 'gzip',
}),
],
};
Function
Allow to specify a custom compression function.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
algorithm(input, compressionOptions, callback) {
return compressionFunction(input, compressionOptions, callback);
},
}),
],
};
compressionOptions
Type: Object
Default: { level: 9 }
Compression options for algorithm
.
You can find all options here zlib.
ℹ️ If you use custom function for the
algorithm
option, the default value is{}
.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
compressionOptions: { level: 1 },
}),
],
};
threshold
Type: Number
Default: 0
Only assets bigger than this size are processed. In bytes.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
threshold: 8192,
}),
],
};
minRatio
Type: 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,
}),
],
};
filename
Type: String|Function
Default: "[path][base].gz"
The target asset filename.
String
For 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',
}),
],
};
Function
webpack.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.filename)) {
return 'assets/svg/[path][base].gz';
}
return 'assets/js/[path][base].gz';
},
}),
],
};
deleteOriginalAssets
Type: Boolean | 'keep-source-map'
Default: false
Whether to delete the original assets or not.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
deleteOriginalAssets: true,
}),
],
};
To exclude sourcemaps from compression
module.exports = {
plugins: [
new CompressionPlugin({
exclude: /.map$/
deleteOriginalAssets: 'keep-source-map',
}),
],
};
Prepare compressed versions of assets using zopfli
library.
ℹ️
@gfx/zopfli
require minimum8
version 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]: 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]: 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' },
],
}),
],
};
ℹ️
copy-webpack-plugin
is 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-server
to write files to the output directory during development, you can force it with thewriteToDisk
option or thewrite-file-webpack-plugin
.
ℹ️ You can get the original source filename from Asset Objects.
Name | Type | Description |
---|---|---|
patterns | {Array<String|Object>} | Specify file related patterns for plugin |
options | {Object} | Specify options for plugin |
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 |
---|---|---|---|
from | {String} | undefined | Glob or path from where we copy files. |
to | {String|Function} | compiler.options.output | Output path. |
context | {String} | options.context || compiler.options.context | A path that determines how to interpret the from path. |
globOptions | {Object} | undefined | Options passed to the glob pattern matching library including ignore option. |
filter | {Function} | undefined | Allows to filter copied assets. |
toType | {String} | undefined | Determinate what is to option - directory, file or template. |
force | {Boolean} | false | Overwrites files already in compilation.assets (usually added by other plugins/loaders). |
priority | {Number} | 0 | Allows you to specify the copy priority. |
transform | {Object} | undefined | Allows to modify the file contents. Enable transform caching. You can use { transform: {cache: { key: 'my-cache-key' }} } to invalidate the cache. |
transformAll | {Function} | undefined | Allows you to modify the contents of multiple files and save the result to one file. |
noErrorOnMissing | {Boolean} | false | Doesn't generate an error on missing file(s). |
info | {Object|Function} | undefined | Allows to add assets info. |
from
Type: String
Default: undefined
Glob or path from where we copy files.
Globs accept fast-glob pattern-syntax.
Glob can only be a string
.
⚠️ Don't use directly
\\
infrom
option 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 windows
If 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
to
Type: String|Function
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/
orpath
methods.
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]',
},
],
}),
],
};
Allows to modify the writing path.
⚠️ Don't return directly
\\
into
(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/
orpath
methods.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to({ context, absoluteFilename }) {
return 'dest/newPath/[name][ext]';
},
},
],
}),
],
};
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to({ context, absoluteFilename }) {
return Promise.resolve('dest/newPath/[name][ext]');
},
},
],
}),
],
};
context
Type: 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/
orpath
methods.
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
globOptions
Type: Object
Default: undefined
Allows to configure 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/**'],
},
},
],
}),
],
};
filter
Type: Function
Default: undefined
ℹ️ To ignore files by path please use the
globOptions.ignore
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;
},
},
],
}),
],
};
toType
Type: 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 |
---|---|---|---|
'dir' | {String} | undefined | If to has no extension or ends on '/' |
'file' | {String} | undefined | If to is not a directory and is not a template |
'template' | {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].[contenthash][ext]',
toType: 'template',
},
],
}),
],
};
force
Type: 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,
},
],
}),
],
};
priority
Type: Number
Default: 0
Allows to specify the priority of copying files with the same destination name.
Files for patterns with higher priority will be copied later.
To overwrite files, the force
option must be enabled.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
// Copied second and will overwrite "dir_2/file.txt"
{
from: 'dir_1/file.txt',
to: 'newfile.txt',
force: true,
priority: 10,
},
// Copied first
{
from: 'dir_2/file.txt',
to: 'newfile.txt',
priority: 5,
},
],
}),
],
};
transform
Type: Function|Object
Default: undefined
Allows to modify the file contents.
Function
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);
},
},
],
}),
],
};
Object
Name | Type | Default | Description |
---|---|---|---|
transformer | {Function} | undefined | Allows to modify the file contents. |
cache | {Boolean|Object} | false | Enable transform caching. You can use transform: { cache: { key: 'my-cache-key' } } to invalidate the cache. |
transformer
Type: Function
Default: undefined
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: {
transformer(content, absoluteFrom) {
return optimize(content);
},
},
},
],
}),
],
};
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
transform: {
transformer(content, path) {
return Promise.resolve(optimize(content));
},
},
},
],
}),
],
};
cache
Type: Boolean|Object
Default: false
webpack.config.js
Enable/disable and configure caching.
Default path to cache directory: node_modules/.cache/copy-webpack-plugin
.
Boolean
Enables/Disable transform
caching.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
transform: {
transformer(content, path) {
return optimize(content);
},
cache: true,
},
},
],
}),
],
};
Object
Enables transform
caching and setup cache directory and invalidation keys.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/*.png',
to: 'dest/',
transform: {
transformer(content, path) {
return optimize(content);
},
cache: {
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: {
transformer(content, path) {
return optimize(content);
},
cache: {
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: {
transformer(content, path) {
return optimize(content);
},
cache: {
directory: path.resolve(__dirname, 'cache-directory'),
keys: async (defaultCacheKeys, absoluteFrom) => {
const keys = await getCustomCacheInvalidationKeysAsync();
return {
...defaultCacheKeys,
keys,
};
},
},
},
},
],
}),
],
};
transformAll
类型:Function
默认值:undefined
允许你去更改多个文件的内容,并将结果保存到一个文件中。
ℹ️ 必须指定
to
配置项为一个文件。只允许使用[contenthash]
与[fullhash]
模板字符串。
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: 'src/**/*.txt',
to: 'dest/file.txt',
// `assets` 参数是一个符合 pattern.from ("src/**/*.txt") 静态资源数组。
transformAll(assets) {
const result = assets.reduce((accumulator, asset) => {
// 静态资源内容可以使用 `source` 方法从 `asset.source` 中获取。
// 静态资源内容是一个 [`Buffer`](https://nodejs.org/api/buffer.html) 对象,可以使用 `content.toString()` 将其转为 `String`
const content = asset.data;
accumulator = `${accumulator}${content}\n`;
return accumulator;
}, '');
return result;
},
},
],
}),
],
};
noErrorOnMissing
Type: 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,
},
],
}),
],
};
info
Type: Object|Function<Object>
Default: undefined
Allows to add assets info.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
'relative/path/to/file.ext',
{
from: '**/*',
// Terser skip this file for minimization
info: { minimized: true },
},
],
}),
],
};
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
'relative/path/to/file.ext',
{
from: '**/*',
// Terser skip this file for minimization
info: (file) => ({ minimized: true }),
},
],
}),
],
};
Name | Type | Default | Description |
---|---|---|---|
concurrency | {Number} | 100 | Limits the number of simultaneous requests to fs |
concurrency
limits 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/**',
],
},
},
],
}),
],
};
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: '[name][ext]',
},
],
}),
],
};
Result:
file-1.txt
file-2.txt
nested-file.txt
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
// When copying files starting with a dot, must specify the toType option
// toType: "file",
to({ context, absoluteFilename }) {
return `newdirectory/${path.relative(context, absoluteFilename)}`;
},
from: 'directory',
},
],
}),
],
};
Result:
"newdirectory/file-1.txt",
"newdirectory/nestedfile.txt",
"newdirectory/nested/deep-nested/deepnested.txt",
"newdirectory/nested/nestedfile.txt",
Useful if you need to simply copy *.js
files to destination "as is" without evaluating and minimizing them using Terser.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
'relative/path/to/file.ext',
{
from: '**/*',
// Terser skip this file for minimization
info: { minimized: true },
},
],
}),
],
};
yarn workspaces
and monorepos
当时用 yarn workspaces
或者 monorepos
时,由于包提升方式不同,node_modules 的相对复制路径可能会失效。
为了避免这种情况,请使用 require.resolve
指定复制路径。
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: `${path.dirname(
require.resolve(`${moduleName}/package.json`)
)}/target`,
to: 'target',
},
],
}),
],
};
Please take a moment to read our contributing guidelines if you haven't yet done so.
这个插件使用 cssnano 优化和压缩 CSS。
就像 optimize-css-assets-webpack-plugin 一样,但在 source maps 和 assets 中使用查询字符串会更加准确,支持缓存和并发模式下运行。
首先,你需要安装 css-minimizer-webpack-plugin
:
npm install css-minimizer-webpack-plugin --save-dev
接着在 webpack
配置中加入该插件。示例:
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /.s?css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
],
},
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
// `...`,
new CssMinimizerPlugin(),
],
},
plugins: [new MiniCssExtractPlugin()],
};
这将仅在生产环境开启 CSS 优化。
如果还想在开发环境下启用 CSS 优化,请将 optimization.minimize
设置为 true
:
webpack.config.js
// [...]
module.exports = {
optimization: {
// [...]
minimize: true,
},
};
然后通过你喜欢的方式运行 webpack
。
仅对 devtool
配置项的 source-map
、inline-source-map
、hidden-source-map
与 nosources-source-map
值生效。
为什么呢?因为 CSS 仅支持这些 source map 类型。
插件支持 devtool
并且使用 SourceMapDevToolPlugin
插件。
使用受支持的 devtool
值可以启用 source map 生成。
使用 SourceMapDevToolPlugin
并启用 columns
配置项可以启用 source map 生成。
使用 source map 将错误信息位置映射到 modules 中(这降低了复杂度)。
如果你是用自定义 minify
函数,请阅读 minify
章节以确保正确处理 source map。
选项名 | 类型 | 默认值 | 描述 |
---|---|---|---|
test | String|RegExp|Array<String|RegExp> | /\.css(\?.*)?$/i | 匹配要处理的文件 |
include | String|RegExp|Array<String|RegExp> | undefined | 要引入的文件 |
exclude | String|RegExp|Array<String|RegExp> | undefined | 要排除的文件 |
parallel | Boolean|Number | true | 启用/禁用多进程并行处理。 |
minify | Function|Array<Function> | CssMinimizerPlugin.cssnanoMinify | 允许覆盖默认的 minify 函数。 |
minimizerOptions | Object|Array<Object> | { preset: 'default' } | Cssnano 优化 配置项。 |
warningsFilter | Function<(warning, file, source) -> Boolean> | () => true | 允许过滤掉 css-minimizer 的警告。 |
test
类型:String|RegExp|Array<String|RegExp>
- 默认值:/\.css(\?.*)?$/i
用来匹配文件。
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
test: /\.foo\.css$/i,
}),
],
},
};
include
类型:String|RegExp|Array<String|RegExp>
默认值:undefined
要包含的文件。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
include: /\/includes/,
}),
],
},
};
exclude
类型:String|RegExp|Array<String|RegExp>
默认值:undefined
要排除的文件。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
exclude: /\/excludes/,
}),
],
},
};
parallel
类型:Boolean|Number
默认值:true
使用多进程并发执行,提升构建速度。
运行时默认的并发数:os.cpus().length - 1
。
ℹ️ 并行化可以显著提升构建速度,所以强烈建议使用。 如果启用了并行化,
minimizerOptions
中的包必须通过字符串引入(packageName
或者require.resolve(packageName)
)。在minimizerOptions
获取更多详细信息。
Boolean
启用/禁用多进程并发执行。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
parallel: true,
}),
],
},
};
Number
启用多进程并发执行且设置并发数。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
parallel: 4,
}),
],
},
};
minify
类型:Function|Array<Function>
默认值:CssMinimizerPlugin.cssnanoMinify
允许覆盖默认的 minify 函数。 默认情况下,插件使用 cssnano 包。 对于使用和测试未发布或版本衍生版本很有用。
可选配置:
async (data, inputMap, minimizerOptions) => {return {code: "a{color: red}", map: "...", warnings: [], errors: []}}
⚠️ 启用
parallel
选项时,始终在minify
函数中使用require
。
Function
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
level: {
1: {
roundingPrecision: 'all=3,px=5',
},
},
},
minify: CssMinimizerPlugin.cleanCssMinify,
}),
],
},
};
Array
如果 minify
配置项传入一个数组,minimizerOptions
也必须是个数组。
miniify
数组中的函数索引对应于 minimizerOptions
数组中具有相同索引的 options 对象。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: [
{}, // 第一个函数的配置项(CssMinimizerPlugin.cssnanoMinify)
{}, // 第二个函数的配置项(CssMinimizerPlugin.cleanCssMinify)
{}, // 第三个函数的配置项
],
minify: [
CssMinimizerPlugin.cssnanoMinify,
CssMinimizerPlugin.cleanCssMinify,
async (data, inputMap, minimizerOptions) => {
// To do something
return {
code: `a{color: red}`,
map: `{"version": "3", ...}`,
warnings: [],
errors: [],
};
},
],
}),
],
},
};
minimizerOptions
类型:Object|Array<Object>
默认值:{ preset: 'default' }
Cssnano 优化 选项.
Object
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
preset: [
'default',
{
discardComments: { removeAll: true },
},
],
},
}),
],
},
};
Array
miniify
数组中的函数索引对应于 minimizerOptions
数组中具有相同索引的 options 对象。
如果你使用了类似于 minimizerOptions
的对象,那么所有函数都会接受它。
如果启用了并行化,
minimizerOptions
中的包必须通过字符串引入(packageName
或者require.resolve(packageName)
)。在这种情况下,我们不应该使用require
/import
。
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
preset: require.resolve('cssnano-preset-simple'),
},
}),
],
},
};
processorOptions
(⚠ only cssnano)类型:Object
默认值:{ from: assetName }
允许配置 cssnano 的 processoptions
配置项。
parser
、 stringifier
和 syntax
可以是一个函数,也可以是一个字符串,用来表示将会被导出的模块。
⚠️ 如果传入一个函数,则必须禁用
parallel
配置项。.
import sugarss from 'sugarss';
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
parallel: false,
minimizerOptions: {
processorOptions: {
parser: sugarss,
},
},
}),
],
},
};
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
processorOptions: {
parser: 'sugarss',
},
},
}),
],
},
};
warningsFilter
类型:Function<(warning, file, source) -> Boolean>
默认值:() => true
允许过滤 css-minimizer warnings(默认使用 cssnano)。
返回 true
将保留 warning,否则返回假值(false
/null
/undefined
)。
⚠️ 如果没有使用 source maps,
source
参数将包含undefined
。
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;
},
}),
],
},
};
不要忘记为所有 loader 启用 sourceMap
选项。
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
devtool: 'source-map',
module: {
loaders: [
{
test: /.s?css$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { sourceMap: true } },
{ loader: 'sass-loader', options: { sourceMap: true } },
],
},
],
},
optimization: {
minimizer: [new CssMinimizerPlugin()],
},
plugins: [new MiniCssExtractPlugin()],
};
移除所有注释(包括以 /*!
开头的注释)。
module.exports = {
optimization: {
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
preset: [
'default',
{
discardComments: { removeAll: true },
},
],
},
}),
],
},
};
webpack.config.js
module.exports = {
devtool: 'source-map',
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minify: CssMinimizerPlugin.cssoMinify,
// Uncomment this line for options
// minimizerOptions: { restructure: false },
}),
],
},
};
webpack.config.js
module.exports = {
devtool: 'source-map',
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minify: CssMinimizerPlugin.cleanCssMinify,
// Uncomment this line for options
// minimizerOptions: { compatibility: 'ie11,-properties.merging' },
}),
],
},
};
webpack.config.js
module.exports = {
devtool: 'source-map',
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minify: CssMinimizerPlugin.esbuildMinify,
}),
],
},
};
如果你还没有阅读,请花一点时间阅读我们的贡献指南。
DefinePlugin
允许在 编译时 将你代码中的变量替换为其他值或表达式。这在需要根据开发模式与生产模式进行不同的操作时,非常有用。例如,如果想在开发构建中进行日志记录,而不在生产构建中进行,就可以定义一个全局常量去判断是否记录日志。这就是 DefinePlugin
的发光之处,设置好它,就可以忘掉开发环境和生产环境的构建规则。
new webpack.DefinePlugin({
// 定义...
});
传递给 DefinePlugin
的每个键都是一个标识符或多个以 .
连接的标识符。
typeof
作为前缀,它会被定义为 typeof 调用。这些值将内联到代码中,从而允许通过代码压缩来删除冗余的条件判断。
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');
if (!PRODUCTION) {
console.log('Debug info');
}
if (PRODUCTION) {
console.log('Production log');
}
未经 webpack 压缩过的代码:
if (!true) {
console.log('Debug info');
}
if (true) {
console.log('Production log');
}
经过压缩后:
console.log('Production log');
使用 feature flags 在生产/开发构建中可以启用/禁用项目的不同特性。
new webpack.DefinePlugin({
NICE_FEATURE: JSON.stringify(true),
EXPERIMENTAL_FEATURE: JSON.stringify(false),
});
在生产或开发构建中使用不同的服务 URL:
new webpack.DefinePlugin({
SERVICE_URL: JSON.stringify('https://dev.example.com'),
});
runtimeValue
function (getterFunction, [string] | true | object) => 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.
There're two arguments for webpack.DefinePlugin.runtimeValue
function:
The first argument is a function(module, key, version)
that should return the value to be assigned to the definition.
The second argument could either be an array of file paths to watch for or a true
to flag the module as uncacheable. Since 5.26.0, it can also take an object argument with the following properties:
fileDependencies?: string[]
A list of files the function depends on.contextDependencies?: string[]
A list of directories the function depends on.missingDependencies?: string[]
A list of not existing files the function depends on.buildDependencies?: string[]
A list of build dependencies the function depends on.version?: string | () => string
A version of the function.const fileDep = path.resolve(__dirname, 'sample.txt');
new webpack.DefinePlugin({
BUILT_AT: webpack.DefinePlugin.runtimeValue(Date.now, {
fileDependencies: [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
.
DllPlugin
和 DllReferencePlugin
用某种方法实现了拆分 bundles,同时还大幅度提升了构建的速度。"DLL" 一词代表微软最初引入的动态链接库。
此插件用于在单独的 webpack 配置中创建一个 dll-only-bundle。 此插件会生成一个名为 manifest.json
的文件,这个文件是用于让 DllReferencePlugin
能够映射到相应的依赖上。
context
(可选): manifest 文件中请求的 context (默认值为 webpack 的 context)format
(boolean = false):如果为 true
,则 manifest json 文件 (输出文件) 将被格式化。name
:暴露出的 DLL 的函数名(TemplatePaths:[fullhash]
& [name]
)path
:manifest.json 文件的 绝对路径(输出文件)entryOnly
(boolean = true):如果为 true
,则仅暴露入口type
:dll bundle 的类型new webpack.DllPlugin(options);
在给定的 path
路径下创建一个 manifest.json
文件。这个文件包含了从 require 和 import 中 request 到模块 id 的映射。 DllReferencePlugin
也会用到这个文件。
此插件与 output.library
的选项相结合可以暴露出(也称为放入全局作用域)dll 函数。
此插件配置在 webpack 的主配置文件中,此插件会把 dll-only-bundles 引用到需要的预编译的依赖中。
context
:(绝对路径) manifest (或者是内容属性)中请求的上下文extensions
:用于解析 dll bundle 中模块的扩展名 (仅在使用 'scope' 时使用)。manifest
:包含 content
和 name
的对象,或者是一个字符串 —— 编译时用于加载 JSON manifest 的绝对路径content
(可选): 请求到模块 id 的映射(默认值为 manifest.content
)name
(可选):dll 暴露地方的名称(默认值为 manifest.name
)(可参考externals
)scope
(可选):dll 中内容的前缀sourceType
(可选):dll 是如何暴露的 (libraryTarget)new webpack.DllReferencePlugin(options);
通过引用 dll 的 manifest 文件来把依赖的名称映射到模块的 id 上,之后再在需要的时候通过内置的 __webpack_require__
函数来 require
对应的模块
这个插件支持两种模式,分别是作用域(scoped)和映射(mapped)。
dll 中的内容可以使用模块前缀的方式引用,举例来说,设置 scope = 'xyz'
,这个 dll 中的名为 abc
的文件可以通过 require('xyz/abc')
来获取。
dll 中的内容会被映射到当前目录下。如果被 require
的文件与 dll 中的某个文件匹配(解析之后),那么这个 dll 中的文件就会被使用。
由于这是在解析了 dll 中每个文件之后才触发的,因此相同的路径必须能够确保这个 dll bundle 的使用者(不一定是人,可指某些代码)有权限访问。 举例来说, 假如一个 dll bundle 中含有 loadash
库以及文件 abc
, 那么 require("lodash")
和 require("./abc")
都不会被编译进主 bundle 文件中,而是会被 dll 所使用。
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',
});
两个单独的用例,用来分别演示作用域(scope)和上下文(context)。
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),
});
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,
});
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');
}
The following EnvironmentPlugin
configuration provides process.env.GIT_VERSION
(such as "v5.4.0-2-g25139f57f") and process.env.GIT_AUTHOR_DATE
(such as "2020-11-04T12:25:16+01:00") corresponding to the last Git commit of the repository:
const child_process = require('child_process');
function git(command) {
return child_process.execSync(`git ${command}`, { encoding: 'utf8' }).trim();
}
new webpack.EnvironmentPlugin({
GIT_VERSION: git('describe --always'),
GIT_AUTHOR_DATE: git('log -1 --format=%aI'),
});
The 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)
});
eslint-webpack-plugin 3.0 仅支持 webpack 5。对于 webpack 4 请查看 2.x 分支。
该插件使用 eslint
来查找和修复 JavaScript 代码中的问题。
首先,需要安装 eslint-webpack-plugin
:
npm install eslint-webpack-plugin --save-dev
注意: 如果未安装 eslint >= 7
,你还需先通过 npm 安装:
npm install eslint --save-dev
然后把插件添加到你的 webpack 配置。例如:
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
// ...
plugins: [new ESLintPlugin(options)],
// ...
};
你可以传入 eslint 参数。
注意你提供的配置选项会传给 ESLint
类。
这是一组和你在 package.json
与 .eslintrc
所指定选项不同的选项。
查阅 eslint 文档 获取更多详情。
警告: 在 eslint-webpack-plugin 1.x 版本中,配置项会传递给已废弃的 CLIEngine。
context
String
compiler.context
指定文件根目录,类型为字符串。
eslintPath
String
eslint
用于 linting 的 eslint
实例的路径。如果 eslintPath
是类似官方 eslint 的目录,或者指定了 formatter
选项,那么就不需要安装 eslint
了。
extensions
String|Array[String]
'js'
指定需要检查的扩展名。
exclude
String|Array[String]
'node_modules'
指定需要排除的文件及目录。必须是相对于 options.context
的相对路径。
files
String|Array[String]
null
指定目录、文件或 globs ,必须是相对于 options.context
的相对路径。
如果是目录则递归查找所有匹配 options.extensions
选项的文件。
如果是文件或 globs 则忽略 options.extensions
选项。
fix
Boolean
false
启用 ESLint 自动修复特性。
小心: 该选项会修改源文件。
formatter
String|Function
'stylish'
接受一个有单一参数的函数:该参数为 eslint 消息(一个对象)的数组。函数必须返回字符串格式的 output。可以使用官方的 eslint formatters。
lintDirtyModulesOnly
Boolean
false
只对内容修改了的文件进行 lint,启动时跳过 lint 。
threads
Boolean | Number
false
以线程池方式运行 lint 。线程池大小是自动的,除非你指定一个数值。
该插件默认会根据 eslint 错误/警告的数量自动调整错误报告(error reporting)。
你也可以通过 emitError
或 emitWarning
强制开启错误报告行为:
emitError
Boolean
true
总是发送发现的错误 ,设置为 false
以禁用。
emitWarning
Boolean
true
总是发送发现的警告,设置为 false
以禁用。
failOnError
Boolean
true
任何错误都会导致模块构建(module build)失败,设置为 false
禁用。
failOnWarning
Boolean
false
当设置为 true
时,任何警告都会导致模块构建(module build)失败。
quiet
Boolean
false
设置为 true
后,仅处理和报告错误,忽略警告。
outputReport
Boolean|Object
false
把错误输出到一个文件,例如在 Jenkins CI 使用 checkstyle xml 文件。
filePath
为绝对路径或者相对于 webpack 配置: output.path
的相对路径。
你可以为输出文件传入不同的 formatter
。
如果没有传入,则使用默认的或已配置的 formatter 。
本插件可以为 source map 的生成提供更好更细粒度的控制。devtool
中的某些配置会自动使用它。
new webpack.EvalSourceMapDevToolPlugin(options);
支持以下选项:
test
(string|RegExp|array
): 默认值为 .js
和 .css
,为与给定的模块扩展名相匹配的模块,添加 source map。include
(string|RegExp|array
): 为与给定路径相匹配的模块,添加 source map。exclude
(string|RegExp|array
): 排除一些与给定值相匹配的模块,不会为它们生成映射关系。append
(string
): 将给定的值添加到源代码中,通常是 #sourceMappingURL
注释,[url]
在 source map 文件中将会被替换成 url,值为 false
表示不添加。moduleFilenameTemplate
(string
): 查看 output.devtoolModuleFilenameTemplate
。module
(boolean
): 默认值为 true
,表示是否为 loaders 添加 source map。columns
(boolean
): 默认值为 true
,表示是否使用列映射(column mapping)。protocol
(string
): 默认协议名为 webpack-internal://
,允许用户重新定义协议。以下示例演示了此插件的一些常见用例。
可以使用以下代码替换配置选项 devtool: eval-source-map
,并使用等效的自定义插件配置:
module.exports = {
// ...
devtool: false,
plugins: [new webpack.EvalSourceMapDevToolPlugin({})],
};
下面的代码将排除 vendor.js
包中任何模块 source map 的生成:
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,
});
Hot Module Replacement,除此之外还被称为 HMR。
启用 HMR 很容易,且在大多数情况下不需要任何配置。
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,
type: 'asset/resource',
},
],
},
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.
Name | Type | Default | Description |
---|---|---|---|
test | String|RegExp|Array<String|RegExp> | /\.html(\?.*)?$/i | Test to match files against. |
include | String|RegExp|Array<String|RegExp> | undefined | Files to include. |
exclude | String|RegExp|Array<String|RegExp> | undefined | Files to exclude. |
parallel | Boolean|Number | true | Use multi-process parallel running to improve the build speed. |
minify | Function|Array<Function> | HtmlMinimizerPlugin.htmlMinifierTerser | Allows you to override default minify function. |
minimizerOptions | Object|Array<Object> | { caseSensitive: true, collapseWhitespace: true, conservativeCollapse: true, keepClosingSlash: true, minifyCSS: true, minifyJS: true, removeComments: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, } | Html-minifier-terser optimisations options. |
test
Type: 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,
}),
],
},
};
include
Type: String|RegExp|Array<String|RegExp>
Default: undefined
Files to include.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
include: /\/includes/,
}),
],
},
};
exclude
Type: String|RegExp|Array<String|RegExp>
Default: undefined
Files to exclude.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
exclude: /\/excludes/,
}),
],
},
};
parallel
Type: 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 speed up your build significantly and is therefore highly recommended.
Boolean
Enable/disable multi-process parallel running.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
parallel: true,
}),
],
},
};
Number
Enable multi-process parallel running and set number of concurrent runs.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
parallel: 4,
}),
],
},
};
minify
Type: Function|Array<Function>
Default: HtmlMinimizerPlugin.htmlMinifierTerser
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
require
insideminify
function whenparallel
option enabled.
Function
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 {
code: htmlMinifier.minify(input, minimizerOptions),
warnings: [],
errors: [],
};
},
}),
],
},
};
Array
If an array of functions is passed to the minify
option, the minimizerOptions
can be an array or an object.
If minimizerOptions
is array, the function index in the minify
array corresponds to the options object with the same index in the minimizerOptions
array.
If you use minimizerOptions
like object, all minify
function accept it.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
minimizerOptions: [
// Options for the first function (HtmlMinimizerPlugin.htmlMinifierTerser)
{
collapseWhitespace: true,
},
// Options for the second function
{},
],
minify: [
HtmlMinimizerPlugin.htmlMinifierTerser,
(data, minimizerOptions) => {
const [[filename, input]] = Object.entries(data);
// To do something
return {
code: `optimised code`,
warnings: [],
errors: [],
};
},
],
}),
],
},
};
minimizerOptions
Type: Object|Array<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.
Object
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
minimizerOptions: {
collapseWhitespace: false,
},
}),
],
},
};
Array
The function index in the minify
array corresponds to the options object with the same index in the minimizerOptions
array.
If you use minimizerOptions
like object, all minify
function accept it.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
minimizerOptions: [
// Options for the first function (HtmlMinimizerPlugin.htmlMinifierTerser)
{
collapseWhitespace: true,
},
// Options for the second function
{},
],
minify: [
HtmlMinimizerPlugin.htmlMinifierTerser,
(data, minimizerOptions) => {
const [[filename, input]] = Object.entries(data);
// To do something
return {
code: `optimised code`,
warnings: [],
errors: [],
};
},
],
}),
],
},
};
Please take a moment to read our contributing guidelines if you haven't yet done so.
HtmlWebpackPlugin
简化了 HTML 文件的创建,以便为你的 webpack 包提供服务。这对于那些文件名中包含哈希值,并且哈希值会随着每次编译而改变的 webpack 包特别有用。你可以让该插件为你生成一个 HTML 文件,使用 lodash 模板提供模板,或者使用你自己的 loader。
npm install --save-dev html-webpack-plugin
该插件将为你生成一个 HTML5 文件,
在 body 中使用 script
标签引入你所有 webpack 生成的 bundle。
只需添加该插件到你的 webpack 配置中,如下所示:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: 'index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'index_bundle.js',
},
plugins: [new HtmlWebpackPlugin()],
};
这将会生成一个包含以下内容的 dist/index.html
文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>webpack App</title>
</head>
<body>
<script src="index_bundle.js"></script>
</body>
</html>
如果你有多个 webpack 入口,他们都会在已生成 HTML 文件中的 <script>
标签内引入。
如果在 webpack 的输出中有任何 CSS 资源(例如,使用 MiniCssExtractPlugin 提取的 CSS),那么这些资源也会在 HTML 文件 <head>
元素中的 <link>
标签内引入。
获取所有的配置选项,请浏览插件文档。
该插件支持第三方插件。详细列表参阅文档。
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 });
checkResource (resource, context)
A Filter function that receives resource
and context
as arguments, must return boolean.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({ resourceRegExp: /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 webpack to optimize (compress) all images using imagemin. Do not worry about size of images, now they are always optimized/compressed.
This plugin can use 2 tools to compress images:
imagemin
- optimize your images by default, since it is stable and works with all types of imagessquoosh
- while working in experimental mode with .jpg
, .jpeg
, .png
, .webp
, .avif
file types.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
For imagemin-svgo
v9.0.0+ need use svgo configuration
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
const { extendDefaultPlugins } = require('svgo');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
},
],
},
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 configuration here https://github.com/svg/svgo#configuration
[
'svgo',
{
plugins: extendDefaultPlugins([
{
name: 'removeViewBox',
active: false,
},
{
name: 'addAttributesToSVGElement',
params: {
attributes: [{ xmlns: 'http://www.w3.org/2000/svg' }],
},
},
]),
},
],
],
},
}),
],
};
squoosh
npm install @squoosh/lib --save-dev
Recommended @squoosh/lib
options for lossy optimization
For lossy optimization we recommend using the default settings @squoosh/lib
.
The default values and supported file types for each option can be found in the [codecs.ts]
(https://github.com/GoogleChromeLabs/squoosh/blob/dev/libsquoosh/src/codecs.ts) file under codecs
.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png)$/i,
type: 'asset',
},
],
},
plugins: [
new ImageMinimizerPlugin({
minify: ImageMinimizerPlugin.squooshMinify,
}),
],
};
Recommended squoosh
options for lossless optimization
For lossless optimization we recommend using the options listed below in minimizerOptions.encodeOptions
.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png)$/i,
type: 'asset',
},
],
},
plugins: [
new ImageMinimizerPlugin({
minify: ImageMinimizerPlugin.squooshMinify,
minimizerOptions: {
encodeOptions: {
mozjpeg: {
// That setting might be close to lossless, but it’s not guaranteed
// https://github.com/GoogleChromeLabs/squoosh/issues/85
quality: 100,
},
webp: {
lossless: 1,
},
avif: {
// https://github.com/GoogleChromeLabs/squoosh/blob/dev/codecs/avif/enc/README.md
cqLevel: 0,
},
},
},
}),
],
};
ℹ️ If you want to use
loader
orplugin
standalone see sections below, but this is not recommended.
In your webpack.config.js
, add the ImageMinimizerPlugin.loader
and specify the asset modules options:
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: ImageMinimizerPlugin.loader,
options: {
severityError: 'warning', // Ignore errors on corrupted images
minimizerOptions: {
plugins: ['gifsicle'],
},
},
},
],
},
],
},
};
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
},
],
},
plugins: [
// Make sure that the plugin placed after any plugins that added images
new ImageMinimizerPlugin({
severityError: 'warning', // Ignore errors on corrupted images
minimizerOptions: {
plugins: ['gifsicle'],
},
// Disable `loader`
loader: false,
}),
],
};
Name | Type | Default | Description |
---|---|---|---|
test | {String\/RegExp|Array<String|RegExp>} | /.(jpe?g|png|gif|tif|webp|svg|avif)$/i | Test to match files against |
include | {String\/RegExp|Array<String|RegExp>} | undefined | Files to include |
exclude | {String\/RegExp|Array<String|RegExp>} | undefined | Files to exclude |
filter | {Function} | () => true | Allows filtering of images for optimization |
severityError | {String} | 'error' | Allows to choose how errors are displayed |
minify | {Function | Array<Function>} | ImageMinimizerPlugin.imageminMinify | Allows to override default minify function |
minimizerOptions | {Object|Array<Object>} | { plugins: [] } | Options for imagemin |
loader | {Boolean} | true | Automatically adding imagemin-loader |
maxConcurrency | {Number} | Math.max(1, os.cpus().length - 1) | Maximum number of concurrency optimization processes in one time |
filename | {string|Function} | '[path][name][ext]' | Allows to set the filename for the generated asset. Useful for converting to a webp |
deleteOriginalAssets | {Boolean} | false | Allows to delete the original asset. Useful for converting to a webp and remove original assets |
test
Type: 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,
}),
],
};
include
Type: 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/,
}),
],
};
exclude
Type: 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/,
}),
],
};
filter
Type: 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;
},
}),
],
};
severityError
Type: String
Default: 'error'
Allows to choose how errors are displayed.
Сan have the following values:
'off'
- suppresses errors and warnings'warning'
- emit warnings instead errors'error'
- emit errorswebpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
severityError: 'warning',
}),
],
};
minify
Type: Function|Array<Function>
Default: ImageMinimizerPlugin.imageminMinify
Allows to override default minify function. By default plugin uses imagemin package. Useful for using and testing unpublished versions or forks.
Аvailable minifiers:
Function
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
minify: async (data, minimizerOptions) => {
const [[, input]] = Object.entries(data);
let result;
try {
result = await minifyAndReturnBuffer(input);
} catch (error) {
// Return original input if there was an error
return { data: input, errors: [error] };
}
return { data: result, warnings: [], errors: [] };
},
minimizerOptions: {},
}),
],
};
Array
If an array of functions is passed to the minify
option, the minimizerOptions
can be an array or an object.
If minimizerOptions
is array, the function index in the minify
array corresponds to the options object with the same index in the minimizerOptions
array.
If you use minimizerOptions
like object, all minify
function accept it.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
minify: [
ImageMinimizerPlugin.imageminMinify,
(data, minimizerOptions) => {
const [[, input]] = Object.entries(data);
let result;
try {
result = minifyAndReturnBuffer(input);
} catch (error) {
// Return original input if there was an error
return { data: input, errors: [error] };
}
return { data: result, warnings: [], errors: [] };
},
],
minimizerOptions: [
// Options for the first function (ImageMinimizerPlugin.imageminMinify)
{
plugins: ['gifsicle', 'mozjpeg', 'pngquant', 'svgo'],
},
// Options for the second function
{},
],
}),
],
};
minimizerOptions
Type: Object|Array<Object>
Default: { plugins: [] }
Options for minify
functions. imagemin
is default minify function.
More information and examples here.
Object
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 },
],
],
},
}),
],
};
Array
The function index in the minify
array corresponds to the options object with the same index in the minimizerOptions
array.
If you use minimizerOptions
like object, all minify
function accept it.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
minify: [
ImageMinimizerPlugin.imageminMinify,
async (data, minimizerOptions) => {
const [[, input]] = Object.entries(data);
let result;
try {
result = await minifyAndReturnBuffer(input);
} catch (error) {
// Return original input if there was an error
return { data: input, errors: [error] };
}
return { data: result, warnings: [], errors: [] };
},
],
minimizerOptions: [
// Options for the first function (ImageMinimizerPlugin.imageminMinify)
{
plugins: ['gifsicle', 'mozjpeg', 'pngquant', 'svgo'],
},
// Options for the second function
{},
],
}),
],
};
loader
Type: Boolean
Default: true
Automatically adding imagemin-loader
.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
plugins: [
new ImageMinimizerPlugin({
loader: false,
}),
],
};
maxConcurrency
Type: 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,
}),
],
};
filename
Type: String|Function
Default: '[path][name][ext]'
Allows to set the filename for the generated asset. Useful for converting to a webp
.
Supported values see in webpack template strings
, File-level
section.
String
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'],
},
}),
],
};
Function
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: (pathData, assetInfo) => {
if (/imageLg/i.test(pathData.filename)) {
return './bigImages/[path][name].webp';
}
return '[path][name].webp';
},
minimizerOptions: {
plugins: ['imagemin-webp'],
},
}),
],
};
webp
using ImageMinimizerPlugin.squooshMinify
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
/*
const defaultTargets = {
".png": "oxipng",
".jpg": "mozjpeg",
".jpeg": "mozjpeg",
".jxl": "jxl",
".webp": "webp",
".avif": "avif",
};
*/
module.exports = {
plugins: [
// Images are converted to `webp` and the original assets have been kept
new ImageMinimizerPlugin({
test: /\.(png)$/i,
filename: '[path][name].webp',
minify: ImageMinimizerPlugin.squooshMinify,
minimizerOptions: {
targets: {
'.png': 'webp',
},
},
}),
],
};
deleteOriginalAssets
Type: Boolean
Default: false
Allows to remove original assets. Useful for converting to a webp
and remove original assets
ℹ️ Doesn't make sense if you haven't changed the original value of the
filename
option
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 |
---|---|---|---|
filter | {Function} | undefined | Allows filtering of images for optimization |
severityError | {String} | 'error' | Allows to choose how errors are displayed |
minify | {Function | Array<Function>} | ImageMinimizerPlugin.imageminMinify | Allows to override default minify function |
minimizerOptions | {Object|Array<Object>} | { plugins: [] } | Options for imagemin |
filename | {string|Function} | '[path][name][ext]' | Allows to set the filename for the generated asset. Useful for converting to a webp |
deleteOriginalAssets | {Boolean} | false | Allows to delete the original asset. Useful for converting to a webp and remove original assets |
filter
Type: 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,
type: 'asset',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
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'],
},
},
},
],
},
],
},
};
severityError
Type: String
Default: 'error'
Allows to choose how errors are displayed.
Сan have the following values:
'off'
- suppresses errors and warnings'warning'
- emit warnings instead errors'error'
- emit errorswebpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: ImageMinimizerPlugin.loader,
options: {
severityError: 'warning',
minimizerOptions: {
plugins: ['gifsicle'],
},
},
},
],
},
],
},
};
minify
Type: Function|Array<Function>
Default: ImageMinimizerPlugin.imageminMinify
Allows to override default minify function. By default plugin uses imagemin package. Useful for using and testing unpublished versions or forks.
Аvailable minifiers:
Function
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: ImageMinimizerPlugin.loader,
options: {
minify: async (data, minimizerOptions) => {
const [[, input]] = Object.entries(data);
let result;
try {
result = await minifyAndReturnBuffer(input);
} catch (error) {
// Return original input if there was an error
return { data: input, errors: [error] };
}
return { data: result, warnings: [], errors: [] };
},
minimizerOptions: {},
},
},
],
},
],
},
};
Array
If an array of functions is passed to the minify
option, the minimizerOptions
can be an array or an object.
If minimizerOptions
is array, the function index in the minify
array corresponds to the options object with the same index in the minimizerOptions
array.
If you use minimizerOptions
like object, all minify
function accept it.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: ImageMinimizerPlugin.loader,
options: {
minify: [
ImageMinimizerPlugin.imageminMinify,
async (data, minimizerOptions) => {
const [[, input]] = Object.entries(data);
let result;
try {
result = await minifyAndReturnBuffer(input);
} catch (error) {
// Return original input if there was an error
return { data: input, errors: [error] };
}
return { data: result, warnings: [], errors: [] };
},
],
minimizerOptions: [
// Options for the first function (ImageMinimizerPlugin.imageminMinify)
{
plugins: ['gifsicle', 'mozjpeg', 'pngquant', 'svgo'],
},
// Options for the second function
{},
],
},
},
],
},
],
},
};
minimizerOptions
Type: Object|Array<Object>
Default: { plugins: [] }
Options for minify
functions. imagemin
is default minify function.
More information and examples here.
Object
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: ImageMinimizerPlugin.loader,
options: {
minimizerOptions: {
plugins: [
['gifsicle', { interlaced: true, optimizationLevel: 3 }],
],
},
},
},
],
},
],
},
};
Array
The function index in the minify
array corresponds to the options object with the same index in the minimizerOptions
array.
If you use minimizerOptions
like object, all minify
function accept it.
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: ImageMinimizerPlugin.loader,
options: {
minify: [
ImageMinimizerPlugin.imageminMinify,
async (data, minimizerOptions) => {
const [[, input]] = Object.entries(data);
let result;
try {
result = await minifyAndReturnBuffer(input);
} catch (error) {
// Return original input if there was an error
return { data: input, errors: [error] };
}
return { data: result, warnings: [], errors: [] };
},
],
minimizerOptions: [
// Options for the first function (ImageMinimizerPlugin.imageminMinify)
{
plugins: [
['gifsicle', { interlaced: true, optimizationLevel: 3 }],
],
},
// Options for the second function
{},
],
},
},
],
},
],
},
};
filename
Type: String|Function
Default: '[path][name][ext]'
Allows to set the filename for the generated asset. Useful for converting to a webp
.
Supported values see in webpack template strings
, File-level
section.
String
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif)$/i,
use: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
},
{
loader: ImageMinimizerPlugin.loader,
options: {
filename: '[path][name].webp',
minimizerOptions: {
plugins: ['imagemin-webp'],
},
},
},
],
},
],
},
};
Function
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif)$/i,
use: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
},
{
loader: ImageMinimizerPlugin.loader,
options: {
filename: (pathData, assetInfo) => {
if (/imageLg/i.test(pathData.filename)) {
return './bigImages/[path][name].webp';
}
return '[path][name].webp';
},
minimizerOptions: {
plugins: ['imagemin-webp'],
},
},
},
],
},
],
},
};
deleteOriginalAssets
Type: Boolean
Default: false
Allows to keep the original asset. Useful for converting to a webp
and remove original assets.
ℹ️ Doesn't make sense if you haven't changed the original value of the
filename
option
webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(png)$/i,
use: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: 'asset',
},
{
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'],
},
},
},
],
},
],
},
};
imageminNormalizeConfig(config)
The function normalizes configuration (converts plugins names and options to Function
s) for using in imagemin
package directly.
const imagemin = require('imagemin');
const { imageminNormalizeConfig } = require('image-minimizer-webpack-plugin');
const imageminConfig = imageminNormalizeConfig({
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 }]],
},
}),
],
};
webp
const 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.
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 installation
will happen automatically to install & save missing dependencies while you work!
npm install --save-dev install-webpack-plugin
In your webpack.config.js
:
plugins: [
new InstallPlugin()
],
This is equivalent to:
plugins: [
new InstallPlugin({
dependencies: {
peer: true,
},
packageManager: {
type: this.getDefaultPackageManager(),
options: {
dev: false,
quiet: false,
},
},
prompt: true,
});
],
Type: Object
Dependencies related options.
Type: Boolean
Default: true
Install missing peer dependencies.
plugins: [
new InstallPlugin({
dependencies: {
peer: true,
}
}),
],
Type: 'npm' | 'yarn' | 'pnpm' | Object | Function
Package manager to use for installing dependencies.
plugins: [
new InstallPlugin({
packageManager: 'yarn'
},
}),
],
You can provide a Function
to the packageManager
to make it dynamic:
plugins: [
new InstallPlugin({
packageManager: function(module, path) {
return [
"babel-preset-react-hmre",
"webpack-dev-middleware",
"webpack-hot-middleware",
].indexOf(module) !== -1;
},
}),
],
Type: 'npm' | 'yarn' | 'pnpm'
Name of package manager to use for installing dependencies.
Type: Object
Package manager related options.
Type: Array
Provide custom arguments to use with package manager.
plugins: [
new InstallPlugin({
packageManager: {
type: 'npm',
options: {
arguments: ['--ignore-scripts']
}
}
},
}),
],
Type: Boolean
Default: false
Install as development dependencies.
plugins: [
new InstallPlugin({
packageManager: {
type: 'npm',
options: {
dev: true,
}
}
},
}),
],
Type: Boolean
Default: false
Reduce the amount of console logging.
plugins: [
new InstallPlugin({
packageManager: {
type: 'npm',
options: {
quiet: true,
}
}
},
}),
],
Type: Boolean
Default: true
Show a prompt to confirm installation.
plugins: [
new InstallPlugin({
prompt: true,
},
}),
],
^v5.0.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.
Webpack 拥有丰富的插件接口。webpack 自身的大部分功能都使用这些插件接口。这使得 webpack 很灵活。
插件 | 描述 |
---|---|
BannerPlugin | 为每个 chunk 文件头部添加 banner |
CommonsChunkPlugin | 提取 chunk 之间的公共模块用以共享 |
CompressionWebpackPlugin | 准备好用 Content-Encoding 格式传送的压缩版资源包 |
ContextReplacementPlugin | 重写 require 表达式的推断上下文 |
CopyWebpackPlugin | 复制某个文件或整个文件夹到生成目录中 |
DefinePlugin | 允许创建一个在编译时可配置的全局常量 |
DllPlugin | 拆分 bundles,从而大幅减少构建时间 |
EnvironmentPlugin | 在 process.env 键上使用 DefinePlugin 的简写方式 |
EslintWebpackPlugin | webpack 的 ESLint 插件 |
HotModuleReplacementPlugin | 启用热更新 (HMR) |
HtmlWebpackPlugin | 快速创建 HTML 文件来服务 bundles |
IgnorePlugin | 从 bundles 包中移除某些模块 |
LimitChunkCountPlugin | 设置 chunk 的最小/最大限制,以便更好的控制 chunk |
MinChunkSizePlugin | 确保 chunk 大小在指定限制之上 |
MiniCssExtractPlugin | 为每一个包含了 CSS 的 JS 文件创建一个 CSS 文件 |
NoEmitOnErrorsPlugin | 出现编译错误时,跳过输出阶段 |
NormalModuleReplacementPlugin | 替换与正则表达式匹配的资源 |
NpmInstallWebpackPlugin | 开发时自动安装缺少的依赖 |
ProgressPlugin | 报告编译进度 |
ProvidePlugin | 使用模块但无需使用 import/require |
SourceMapDevToolPlugin | 对 source map 进行更细颗粒度的控制 |
EvalSourceMapDevToolPlugin | 对 eval source map 进行更细颗粒度的控制 |
TerserPlugin | 在你的项目中使用 Terser 插件来压缩 JS |
查找更多第三方插件,请参阅 awesome-webpack。
This is a list of plugins which are used by webpack internally.
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.
EntryPlugin(context, entry, options)
Adds an entry chunk on compilation. The chunk is named options.name
and contains only one module (plus dependencies). The module is resolved from entry
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.
请注意在 webpack.optimize
命名空间下的所有插件应该只在 mode
设置为 'none'
时使用。否则你将会在插件被两次使用时遇到麻烦。
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
.
请查看 ModuleConcatenationPlugin 页面 获取更多内容。
optimize/FlagIncludedChunksPlugin()
Adds chunk ids of chunks which are included in the chunk. This eliminates unnecessary chunk loads.
optimize/RealContentHashPlugin()
When optimization.realContentHash
option is enabled, webpack will apply RealContentHashPlugin
to compiler internally.
RealContentHashPlugin
provides a updateHash
5.8.0+ hook for customizing hash updating:
const webpack = require('webpack');
const RealContentHashPlugin = webpack.optimize.RealContentHashPlugin;
// ...
compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
const hooks = RealContentHashPlugin.getCompilationHooks(compilation);
hooks.updateHash.tap('MyPlugin', (content, oldHash) => {
// you can calculate the hash here as you wish
});
});
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: {
rules: [
{
test: /\.json$/i,
type: 'asset/resource',
},
],
},
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(),
],
},
};
And run webpack
via your preferred method.
Name | Type | Default | Description |
---|---|---|---|
test | String|RegExp|Array<String|RegExp> | /\.json(\?.*)?$/i | Test to match files against. |
include | String|RegExp|Array<String|RegExp> | undefined | Files to include. |
exclude | String|RegExp|Array<String|RegExp> | undefined | Files to exclude. |
minimizerOptions | Object | { replacer: null, space: null } | JSON.stringify() options. |
test
Type: 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,
}),
],
},
};
include
Type: String|RegExp|Array<String|RegExp>
Default: undefined
Files to include.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
include: /\/includes/,
}),
],
},
};
exclude
Type: String|RegExp|Array<String|RegExp>
Default: undefined
Files to exclude.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
exclude: /\/excludes/,
}),
],
},
};
minimizerOptions
Type: 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:
number
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,
}),
],
};
Keeping chunk size above the specified limit is no longer a feature of this plugin. Use MinChunkSizePlugin 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
本插件会将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。
本插件基于 webpack v5 的新特性构建,并且需要 webpack 5 才能正常工作。
与 extract-text-webpack-plugin 相比:
首先,你需要安装 mini-css-extract-plugin
:
npm install --save-dev mini-css-extract-plugin
建议 mini-css-extract-plugin
与 css-loader
一起使用。
之后将 loader 与 plugin 添加到你的 webpack
配置文件中。 例如:
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"],
},
],
},
};
⚠️ 注意,如果你从 webpack 入口处导入 CSS 或者在 初始 chunk 中引入 style,
mini-css-extract-plugin
则不会将这些 CSS 加载到页面中。请使用html-webpack-plugin
自动生成link
标签或者在创建index.html
文件时使用link
标签。
⚠️ source map 只在
source-map
/nosources-source-map
/hidden-nosources-source-map
/hidden-source-map
值情况下起作用,因为 CSS 仅支持带有sourceMappingURL
注释的 source map (例如//# sourceMappingURL=style.css.map
)。如果你需要将devtool
设置为其他值,你可以使用css-loader
中的sourceMap: true
来启用提取并生成 CSS 的 source map。
选项名 | 类型 | 默认值 | 描述 |
---|---|---|---|
filename | {String|Function} | [name].css | 此选项决定了输出的每个 CSS 文件的名称 |
chunkFilename | {String|Function} | based on filename | 此选项决定了非入口的 chunk 文件名称 |
ignoreOrder | {Boolean} | false | 移除 Order 警告 |
insert | {String|Function} | var head = document.getElementsByTagName("head")[0];head.appendChild(linkTag); | 在指定位置将 非初始(由 async 修饰) 的 CSS chunk 插入 link 标签 |
attributes | {Object} | {} | 为 非初始(由 async 修饰) 的 CSS chunk 所处的 link 标签添加自定义属性 |
linkType | {String|Boolean} | text/css | 允许使用自定义 link 类型加载异步 chunk |
runtime | {Boolean} | true | 允许启动/禁用 runtime 生成 |
experimentalUseImportModule | {Boolean} | undefined | 使用实验性的 webpack API 来执行模块,而非子代编译器 |
filename
类型:String|Function
默认值:[name].css
此选项决定了输出的每个 CSS 文件的名称。
机制类似于 output.filename
。
chunkFilename
类型:String|Function
默认值:based on filename
将
chunkFilename
设置为function
,仅在 webpack@5 下可用。
此选项决定了非入口的 chunk 文件名称
机制类似于 output.chunkFilename
ignoreOrder
类型:Boolean
默认值:false
移除 Order 警告 具体细节请参阅示例。
insert
类型:String|Function
默认值:document.head.appendChild(linkTag);
⚠️ 仅对 非初始(由 async 修饰) chunk 有效。
默认情况下,mini-css-extract-plugin
会将 styles(<link>
元素)附加到当前 window
的 document.head
中。
但在某些情况下,可能需要对附加的目标进行精细化管理,甚至延迟 link
元素的插入。
例如,当你在 iframe 中运行应用程序异步加载样式时,就属于此情况。
对于此类情况,insert
可被配置为函数或自定义的选择器。
如果附加目标为 iframe,请确保父文档有足够的访问权限进入 frame document,并将元素附加到它上面。
String
允许设置自定义的 query selector。
新的 <link>
元素将被插入到找到的 item 之后。
webpack.config.js
new MiniCssExtractPlugin({
insert: "#some-element",
});
找到 id 为 some-element
的元素,在它之后插入新的 <link>
元素。
Function
允许覆盖默认行为,并在任意位置插入样式。
⚠ 注意,这段代码将与你的应用程序一起在浏览器中运行。由于并非所有浏览器都支持 ESMA 特性,如
let
,const
,arrow function expression
等,我们建议只使用 ECMA 5 的特性和语法。
⚠
insert
函数被序列化为字符串并传递给插件。这意味着它将无法访问 webpack 配置模块的作用域。
webpack.config.js
new MiniCssExtractPlugin({
insert: function (linkTag) {
var reference = document.querySelector("#some-element");
if (reference) {
reference.parentNode.insertBefore(linkTag, reference);
}
},
});
找到 id 为 some-element
的元素,在它之后插入新的 <link>
元素。
attributes
类型:Object
默认值:{}
⚠️ 仅对 非初始(由 async 修饰) chunk 有效。
如果定义了此选项,mini-css-extract-plugin
将把指定的属性和值附加到 <link>
元素上。
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"],
},
],
},
};
注意:它只适用于动态加载的 css chunk,如果你想修改 html 文件内的链接属性,请使用 html-webpack-plugin。
linkType
类型:String|Boolean
默认值:text/css
此选项运行使用自定义链接类型加载异步 chunk,例如 <link type="text/css" ...>
。
String
可选值: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"],
},
],
},
};
Boolean
false
禁用 link 的 type
属性
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"],
},
],
},
};
runtime
Type: Boolean
Default: true
允许开启/禁用 runtime 生成。 CSS 仍将被提取,并可用于自定义加载方法。 例如,你可以使用 assets-webpack-plugin 来检索它们,然后当需要时使用你自己的 runtime 代码下载静态资源。
设置为 true
以跳过。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
runtime: false,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
experimentalUseImportModule
类型:Boolean
默认值:undefined
如果没有显式启用,则默认启用(即可以通过 true
与 false
显式控制该配置),并且新 API 处于可用状态(webpack 版本至少为 5.52.0
)。
布尔值在 5.33.2
版本后可用,但是你需要启用 experiments.executeModule
(webpack 5.52.0
版本不需要)。
使用新的 webpack API 来执行模块而不是子编译器。 这大大提高了性能和内存使用。
当与 experiments.layers
相结合时,添加了一个 layer
选项到 loader 配置项中,以指定 CSS 执行的 layer。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// `>= 5.52.0` 版本的 webpack 不需要该配置,因为该配置项默认启用
// 仅 `>= 5.33.2 & <= 5.52.0` 版本的 webpack 需要该配置
// 对于 `<= 5.33.2` 版本的 webpack 不可用/不安全
experimentalUseImportModule: true,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
publicPath | {String|Function} | webpackOptions.output.publicPath | 为图片、文件等外部资源指定一个自定义的公共路径。 |
emit | {Boolean} | true | 如果设为 false,插件将会提取 CSS 但不会 生成文件 |
esModule | {Boolean} | true | 使用 ES modules 语法 |
publicPath
类型:String|Function
默认值:webpackOptions.output
选项中的 publicPath
为 CSS 内的图片、文件等外部资源指定一个自定义的公共路径。
机制类似于 output.publicPath
。
String
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// 类似于 webpackOptions.output 中的选项
// 所有选项都是可选的
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "/public/path/to/",
},
},
"css-loader",
],
},
],
},
};
Function
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// 类似于 webpackOptions.output 中的选项
// 所有选项都是可选的
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",
],
},
],
},
};
emit
类型:Boolean
默认值:true
如果设置为 true,会发送一个文件(向文件系统中写入一个文件)。如果设置为 false,该插件将会提取 CSS 但是 不会 发送文件。 禁用该配置对服务侧的包比较有用。
esModule
类型:Boolean
默认值:true
默认情况下 mini-css-extract-plugin
将会生成使用 ES 模块语法的 JS 模块。
在某些情况下,使用 ES 模块是有益的,比如:module concatenation 和 tree shaking。
你可以使用以下方式启用 CommonJS 语法:
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",
],
},
],
},
};
推荐 production
环境的构建将 CSS 从你的 bundle 中分离出来,这样可以使用 CSS/JS 文件的并行加载。
这可以通过使用 mini-css-extract-plugin
来实现,因为它可以创建单独的 CSS 文件。
对于 development
模式(包括 webpack-dev-server
),你可以使用 style-loader,因为它可以使用多个 标签将 CSS 插入到 DOM 中,并且反应会更快。
i 不要同时使用
style-loader
与mini-css-extract-plugin
。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== "production";
module.exports = {
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
devMode ? "style-loader" : MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader",
],
},
],
},
plugins: [].concat(devMode ? [] : [new MiniCssExtractPlugin()]),
};
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",
],
},
],
},
};
⚠ 命名会被修改为
camelCase
的形式。
⚠ 不允许在 css 的 class name 中使用 JavaScript 关键字。
⚠ 应启用
css-loader
中的esModule
以及modules.namedExport
选项。
styles.css
.foo-baz {
color: red;
}
.bar {
color: blue;
}
index.js
import { fooBaz, bar } from "./styles.css";
console.log(fooBaz, bar);
你可以按照如下配置启用 ES 模块命名导出:
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: "css-loader",
options: {
esModule: true,
modules: {
namedExport: true,
localIdentName: "foo__[name]__[local]",
},
},
},
],
},
],
},
};
publicPath
选项为函数webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// 类似于 webpackOptions.output 中的选项
// 所有选项都是可选的
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) => {
// publicPath 是资源相对于上下文的相对路径
// 例如:对于 ./css/admin/main.css publicPath 将会是 ../../
// 而对于 ./css/main.css publicPath 将会是 ../
return path.relative(path.dirname(resourcePath), context) + '/';
},
},
},
"css-loader",
],
},
],
},
};
此插件不能与 loader 链中的 style-loader
一同使用。
这是一个在 development
构建中使用 HMR 并且在 production
构建中将样式文件提取到独立文件中的示例。
(为了更加清楚的表达,省略了 Loader 的选项,以适应需要。)
如果你使用的是 webpack-dev-server
,那么就无需使用 HotModuleReplacementPlugin
plugin。
webpack-dev-server
使用 hot
选项决定是否启用/禁用 HMR。
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",
],
},
],
},
};
注意:在 webpack 5 中 HMR 已自动支持。无需配置。你可以跳过以下内容:
mini-css-extract-plugin
支持在开发中热重载实际的 CSS 文件。
我们提供了一些选项来启动标准 stylesheets 和本地范围内 CSS 和 CSS modules 的 HMR 支持。
以下是 mini-css 用于启动 HMR CSS modules 的示例配置。
如果你使用的是 webpack-dev-server
,那么你无需使用 HotModuleReplacementPlugin
插件。
webpack-dev-server
使用 hot
选项来控制启用/禁用 HMR。
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",
],
},
],
},
};
为了压缩输出文件,请使用类似于 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(),
],
},
};
这将只在生产模式下启用 CSS 压缩优化。如果你需要在开发模式下使用,请设置 optimization.minimize
选项为 true。
运行时代码通过 <link>
或者<style>
标签检测已经添加的 CSS。
当在服务端注入 CSS 代码 以及做 SSR 时将会很有用。
<link>
标签的 href
属性必须与将要被加载的 CSS chunk 的 URL 相匹配。
data-href
属性也可以被用在 <link>
和 <style>
标签中
使用内联 CSS 时,必须使用 data-href
属性。
用过使用 optimization.splitChunks.cacheGroups
选项,所有的 CSS 可以被提取到一个 CSS 文件中。
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: "styles",
type: "css/mini-extract",
chunks: "all",
enforce: true,
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
请注意在 webpack 5 中应该使用 type
而不是 test
,否则将会生成 .js
文件而不是 .css
。这是因为 test
不知道应该去掉哪个模块(在这种情况下,它不会检测到 .js
应该被删除)。
你可以基于 webpack 的入口名称提取 CSS。 当你使用路由动态加载但是想要通过入口加载对应的 CSS 文件时这将会非常有用。 这样也避免了 ExtractTextPlugin 造成的 CSS 重复复制问题。
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: {
foo: path.resolve(__dirname, "src/foo"),
bar: path.resolve(__dirname, "src/bar"),
},
optimization: {
splitChunks: {
cacheGroups: {
fooStyles: {
type: "css/mini-extract",
name: "styles_foo",
chunks: (chunk) => {
return chunk.name === "foo";
},
enforce: true,
},
barStyles: {
type: "css/mini-extract",
name: "styles_bar",
chunks: (chunk) => {
return chunk.name === "bar";
},
enforce: true,
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
使用 filename
选项,你可以使用 chunk 数据来定制文件名。
这点在处理多个入口,并且希望对给定的 入口/chunk 文件进行更多处理时,非常有用。
下面示例中,我们使用 filename
将生成的 css 输出到不同的目录中。
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"],
},
],
},
};
使用 filename: "[contenthash].css"
启动长期缓存。根据需要添加 [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"],
},
],
},
};
对于通过使用 scoping 或命名约定来解决 css order 的项目,可以通过将插件的 ignoreOrder 选项设置为 true 来禁用 css order 警告。
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"],
},
],
},
};
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: "./src/index.js",
module: {
rules: [
{
test: /\.s[ac]ss$/i,
oneOf: [
{
resourceQuery: "?dark",
use: [
Self.loader,
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: `@use 'dark-theme/vars' as vars;`,
},
},
],
},
{
use: [
Self.loader,
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: `@use 'light-theme/vars' as vars;`,
},
},
],
},
],
},
],
},
plugins: [
new Self({
filename: "[name].css",
attributes: {
id: "theme",
},
}),
],
};
src/index.js
import "./style.scss";
let theme = "light";
const themes = {};
themes[theme] = document.querySelector("#theme");
async function loadTheme(newTheme) {
// eslint-disable-next-line no-console
console.log(`CHANGE THEME - ${newTheme}`);
const themeElement = document.querySelector("#theme");
if (themeElement) {
themeElement.remove();
}
if (themes[newTheme]) {
// eslint-disable-next-line no-console
console.log(`THEME ALREADY LOADED - ${newTheme}`);
document.head.appendChild(themes[newTheme]);
return;
}
if (newTheme === "dark") {
// eslint-disable-next-line no-console
console.log(`LOADING THEME - ${newTheme}`);
import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => {
themes[newTheme] = document.querySelector("#theme");
// eslint-disable-next-line no-console
console.log(`LOADED - ${newTheme}`);
});
}
}
document.onclick = () => {
if (theme === "light") {
theme = "dark";
} else {
theme = "light";
}
loadTheme(theme);
};
src/dark-theme/_vars.scss
$background: black;
src/light-theme/_vars.scss
$background: white;
src/styles.scss
body {
background-color: vars.$background;
}
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Document</title>
<link id="theme" rel="stylesheet" type="text/css" href="./main.css" />
</head>
<body>
<script src="./main.js"></script>
</body>
</html>
如果您想从 CSS 文件中提取媒体查询(因为移动用户不需要加载电脑或平板专用的 CSS ),应使用以下插件之一:
如果你还没有阅读过我们的贡献指南,请花一点时间阅读它。
在过去,webpack 打包时的一个权衡是,打包中的每个模块都会被包裹在单独的函数闭包中。这些包裹的函数使得 JavaScript 在浏览器中执行速度变慢。相比之下,像 Closure Compiler 和 RollupJS 这样的工具会将所有模块的作用域“提升”或合并到一个闭包中,从而使得代码在浏览器中执行速度更快。
此插件将在 webpack 中启用相同的合并行为。默认情况下,此插件在 生产模式 下已启用,在其他情况下则禁用。将 optimization.concatenateModules
选项 设置为 false
即可覆盖在生产模式下的默认优化。手动添加 ModuleConcatenationPlugin
或使用 optimization.concatenateModules
选项可以在其他模式下启用合并行为:
new webpack.optimize.ModuleConcatenationPlugin();
这种合并行为被称为“作用域提升”。
作用域提升是 ECMAScript 模块语法特别支持的一个功能。因此,webpack 可能会根据使用的模块类型和 其他条件 回退到普通的打包方式。
正如文章所解释的,webpack 尝试实现部分作用域提升。它会将模块合并到一个单一的作用域中,但并非在所有情况下都能做到。如果 webpack 无法合并一个模块,则有两种替代方案:阻止与创建新组。阻止意味着该模块必须在自己的作用域中;创建新组意味着会创建一个新的模块组。以下条件决定了不同的输出:
条件 | 输出 |
---|---|
没有 ES6 模块 | 阻止 |
从非导入导入 | 创建新组 |
从其他 chunk 导入 | 创建新组 |
被其他多个模块分组导入 | 创建新组 |
从 import() 语法导入 | 创建新组 |
受 ProvidePlugin 影响或使用 module | 阻止 |
接受 HMR | 创建新组 |
使用 eval() | 阻止 |
在多个 chunk 中 | 阻止 |
export * from "cjs-module" | 阻止 |
下面的伪 JavaScript 代码解释了该算法:
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;
}
如果使用的是 webpack CLI,使用 --stats-optimization-bailout
标志将显示出现 bailout 的原因;如果使用的是 webpack 配置,则需要向 stats
对象添加以下内容:
module.exports = {
//……
stats: {
// 此配置将显示出现 bailout 的原因
optimizationBailout: true,
},
};
The ModuleFederationPlugin
allows a build to provide or consume modules with other independent builds at runtime.
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
// options' typings in typescript
runtime: string | false,
}),
],
};
Create a new runtime chunk with the specified name.
webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
runtime: 'my-runtime-name',
}),
],
};
There are three ways to specify the versions of shared libraries.
This syntax allows you to share libraries with package name only. This approach is good for prototyping, but it will not allow you to scale to large production environment given that libraries like react
and react-dom
will require additional requirements.
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
// adds lodash as shared module
// version is inferred from package.json
// there is no version check for the required version
// so it will always use the higher version found
shared: ['lodash'],
}),
],
};
This syntax provides you more control over each shared library in which you can define package name as the key and version (semver) as the value.
module.exports = {
plugins: [
new ModuleFederationPlugin({
shared: {
// adds lodash as shared module
// version is inferred from package.json
// it will use the highest lodash version that is >= 4.17 and < 5
lodash: '^4.17.0',
},
}),
],
};
This syntax allows you to provide additional hints to each shared package where you define the package name as the key, and the value as an object containing hints to modify sharing behavior.
const deps = require('./package.json').dependencies;
module.exports = {
plugins: [
new ModuleFederationPlugin({
shared: {
// adds react as shared module
react: {
requiredVersion: deps.react,
singleton: true,
},
},
}),
],
};
eager
boolean
This hint will allow webpack to include the provided and fallback module directly instead of fetching the library via an asynchronous request. In other words, this allows to use this shared module in the initial chunk. Also, be careful that all provided and fallback modules will always be downloaded when this hint is enabled.
import
false | string
The provided module that should be placed in the shared scope. This provided module also acts as fallback module if no shared module is found in the shared scope or version isn't valid. (The value for this hint defaults to the property name.)
packageName
string
The package name that is used to determine required version from description file. This is only needed when the package name can't be automatically determined from request.
requiredVersion
false | string
The required version of the package.
shareKey
string
The requested shared module is looked up under this key from the shared scope.
shareScope
string
The name of the shared scope.
singleton
boolean
This hint only allows a single version of the shared module in the shared scope (disabled by default). Some libraries use a global internal state (e.g. react, react-dom). Thus, it is critical to have only one instance of the library running at a time.
strictVersion
boolean
This hint allows webpack to reject the shared module if version is not valid (defaults to true
when local fallback module is available and shared module is not a singleton, otherwise false
, it has no effect if there is no required version specified).
version
false | string
The version of the provided module. It allows webpack to replace lower matching versions, but not higher.
module.exports = {
plugins: [
new ModuleFederationPlugin({
// adds vue as shared module
// version is inferred from package.json
// it will always use the shared version, but print a warning when the shared vue is < 2.6.5 or >= 3
shared: {
vue: {
requiredVersion: '^2.6.5',
singleton: true,
},
},
}),
],
};
module.exports = {
plugins: [
new ModuleFederationPlugin({
// adds vue as shared module
// there is no local version provided
// it will emit a warning if the shared vue is < 2.6.5 or >= 3
shared: {
vue: {
import: false,
requiredVersion: '^2.6.5',
},
},
}),
],
};
module.exports = {
plugins: [
new ModuleFederationPlugin({
// adds vue as shared module
// there is no local version provided
// it will throw an error when the shared vue is < 2.6.5 or >= 3
shared: {
vue: {
import: false,
requiredVersion: '^2.6.5',
strictVersion: true,
},
},
}),
],
};
module.exports = {
plugins: [
new ModuleFederationPlugin({
shared: {
'my-vue': {
// can be referenced by import "my-vue"
import: 'vue', // the "vue" package will be used as a provided and fallback module
shareKey: 'shared-vue', // under this name the shared module will be placed in the share scope
shareScope: 'default', // share scope with this name will be used
singleton: true, // only a single version of the shared module is allowed
strictVersion: true, // don't use shared version when version isn't valid. Singleton or modules without fallback will throw, otherwise fallback is used
version: '1.2.3', // the version of the shared module
requiredVersion: '^1.0.0', // the required version of the shared module
},
},
}),
],
};
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);
注意,resourceRegExp
是针对你在代码中编写的请求进行测试的,而不是解析的资源。例如,当你写了一段 import sum from './sum'
的代码时,'./sum'
将会被用来测试而不是 './sum.js'
。
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
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 get the right configuration imported depending on which target you're building for:
npx webpack --env APP_TARGET=VERSION_A
=> 'I am version A'
npx webpack --env APP_TARGET=VERSION_B
=> 'I am version B'
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();
outputPath
new webpack.debug.ProfilingPlugin({
outputPath: path.join(__dirname, '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!
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.
function
Provide 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);
object
When 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
.
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 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'); // <= works
jQuery('#item'); // <= also 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'],
});
本插件实现了对 source map 生成内容进行更细粒度的控制。它也可以根据 devtool
配置选项的某些设置来自动启用。
new webpack.SourceMapDevToolPlugin(options);
支持以下配置项:
test
(string
RegExp
[string, RegExp]
):包含基于扩展名的模块的 source map(默认是 .js
, .mjs
和 .css
)。include
(string
RegExp
[string, RegExp]
):使路径与该值匹配的模块生成 source map。exclude
(string
RegExp
[string, RegExp]
):使匹配该值的模块不生成 source map。filename
(string
):定义生成的 SourceMap 的名称(不设置将默认置为 inlined)。append
(string
):在原始资源后追加给定值。通常是 #sourceMappingURL
注释。[url]
被替换成 source map 文件的 URL。webpack v4.36.0 之后支持 path 参数:[chunk]
、[filename]
和 [contenthash]
。设置 append
为 false
会禁止追加。moduleFilenameTemplate
(string
):查看 output.devtoolModuleFilenameTemplate
。fallbackModuleFilenameTemplate
(string
):查看上面的链接。namespace
(string
):查看 output.devtoolNamespace
。module = true
(boolean
):表示 loader 是否生成 source map。columns = true
(boolean
):表示是否应该使用 column mapping。noSources = false
(boolean
):防止源文件的内容被包含在 source map 中。publicPath
(string
):生成带 public path 前缀的绝对 URL,例如:https://example.com/project/
。fileContext
(string
):使得 [file]
参数作为本目录的相对路径。sourceRoot
(string
):给 SourceMap 中的 sourceRoot
属性提供一个自定义值。fileContext
配置在你想要将 source map 存储到上层目录,以避免 ../../
出现在绝对路径 [url]
里面时是有用的。
下面的示例展示了本插件的一些常见用例。
你可以使用以下代码将配置项 devtool: inline-source-map
替换为等效的自定义插件配置:
module.exports = {
// ...
devtool: false,
plugins: [new webpack.SourceMapDevToolPlugin({})],
};
以下代码会排除 vendor.js
bundle 内模块的 source map。
new webpack.SourceMapDevToolPlugin({
filename: '[name].js.map',
exclude: ['vendor.js'],
});
设置 source map 的 URL。在宿主环境需要授权的情况下很有用。
new webpack.SourceMapDevToolPlugin({
append: '\n//# sourceMappingURL=https://example.com/sourcemap/[url]',
filename: '[name].map',
});
还有一种场景,source map 存储在上层目录中时:
project
|- dist
|- public
|- bundle-[hash].js
|- sourcemaps
|- bundle-[hash].js.map
如下设置:
new webpack.SourceMapDevToolPlugin({
filename: 'sourcemaps/[file].map',
publicPath: 'https://example.com/project/',
fileContext: 'public',
});
将会生成以下 URL:
https://example.com/project/sourcemaps/bundle-[hash].js.map
最初,chunks(以及内部导入的模块)是通过内部 webpack 图谱中的父子关系关联的。CommonsChunkPlugin
曾被用来避免他们之间的重复依赖,但是不可能再做进一步的优化。
从 webpack v4 开始,移除了 CommonsChunkPlugin
,取而代之的是 optimization.splitChunks
。
开箱即用的 SplitChunksPlugin
对于大部分用户来说非常友好。
默认情况下,它只会影响到按需加载的 chunks,因为修改 initial chunks 会影响到项目的 HTML 文件中的脚本标签。
webpack 将根据以下条件自动拆分 chunks:
node_modules
文件夹当尝试满足最后两个条件时,最好使用较大的 chunks。
webpack 为希望对该功能进行更多控制的开发者提供了一组选项。
下面这个配置对象代表 SplitChunksPlugin
的默认行为。
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
chunks: 'async',
minSize: 20000,
minRemainingSize: 0,
minChunks: 1,
maxAsyncRequests: 30,
maxInitialRequests: 30,
enforceSizeThreshold: 50000,
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
reuseExistingChunk: true,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
};
string = '~'
默认情况下,webpack 将使用 chunk 的来源和名称生成名称(例如 vendors~main.js
)。此选项使你可以指定用于生成名称的分隔符。
string = 'async'
function (chunk)
这表明将选择哪些 chunk 进行优化。当提供一个字符串,有效值为 all
,async
和 initial
。设置为 all
可能特别强大,因为这意味着 chunk 可以在异步和非异步 chunk 之间共享。
Note that it is applied to the fallback cache group as well (splitChunks.fallbackCacheGroup.chunks
).
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
// include all types of chunks
chunks: 'all',
},
},
};
或者,你也可以提供一个函数去做更多的控制。这个函数的返回值将决定是否包含每一个 chunk。
module.exports = {
//...
optimization: {
splitChunks: {
chunks(chunk) {
// exclude `my-excluded-chunk`
return chunk.name !== 'my-excluded-chunk';
},
},
},
};
number = 30
按需加载时的最大并行请求数。
number = 30
入口点的最大并行请求数。
[string] = ['javascript', 'unknown']
Sets the size types which are used when a number is used for sizes.
number = 1
拆分前必须共享模块的最小 chunks 数。
boolean
为由 maxSize 分割的部分创建名称时,阻止公开路径信息。
number = 20000
{ [index: string]: number }
生成 chunk 的最小体积(以 bytes 为单位)。
number
{ [index: string]: number }
生成 chunk 所需的主 chunk(bundle)的最小体积(以字节为单位)缩减。这意味着如果分割成一个 chunk 并没有减少主 chunk(bundle)的给定字节数,它将不会被分割,即使它满足 splitChunks.minSize
。
splitChunks.cacheGroups.{cacheGroup}.enforceSizeThreshold
number = 50000
强制执行拆分的体积阈值和其他限制(minRemainingSize,maxAsyncRequests,maxInitialRequests)将被忽略。
splitChunks.cacheGroups.{cacheGroup}.minRemainingSize
number = 0
在 webpack 5 中引入了 splitChunks.minRemainingSize
选项,通过确保拆分后剩余的最小 chunk 体积超过限制来避免大小为零的模块。 'development' 模式 中默认为 0
。对于其他情况,splitChunks.minRemainingSize
默认为 splitChunks.minSize
的值,因此除需要深度控制的极少数情况外,不需要手动指定它。
splitChunks.cacheGroups.{cacheGroup}.layer
RegExp
string
function
按模块层将模块分配给缓存组。
number = 0
使用 maxSize
(每个缓存组 optimization.splitChunks.cacheGroups[x].maxSize
全局使用 optimization.splitChunks.maxSize
或对后备缓存组 optimization.splitChunks.fallbackCacheGroup.maxSize
使用)告诉 webpack 尝试将大于 maxSize
个字节的 chunk 分割成较小的部分。 这些较小的部分在体积上至少为 minSize
(仅次于 maxSize
)。
该算法是确定性的,对模块的更改只会产生局部影响。这样,在使用长期缓存时就可以使用它并且不需要记录。maxSize
只是一个提示,当模块大于 maxSize
或者拆分不符合 minSize
时可能会被违反。
当 chunk 已经有一个名称时,每个部分将获得一个从该名称派生的新名称。 根据 optimization.splitChunks.hidePathInfo
的值,它将添加一个从第一个模块名称或其哈希值派生的密钥。
maxSize
选项旨在与 HTTP/2 和长期缓存一起使用。它增加了请求数量以实现更好的缓存。它还可以用于减小文件大小,以加快二次构建速度。
number
像 maxSize
一样,maxAsyncSize
可以为 cacheGroups(splitChunks.cacheGroups.{cacheGroup}.maxAsyncSize
)或 fallback 缓存组(splitChunks.fallbackCacheGroup.maxAsyncSize
)全局应用(splitChunks.maxAsyncSize
)
maxAsyncSize
和 maxSize
的区别在于 maxAsyncSize
仅会影响按需加载 chunk。
number
像 maxSize
一样,maxInitialSize
可以对 cacheGroups(splitChunks.cacheGroups.{cacheGroup}.maxInitialSize
)或 fallback 缓存组(splitChunks.fallbackCacheGroup.maxInitialSize
)全局应用(splitChunks.maxInitialSize)。
maxInitialSize
和 maxSize
的区别在于 maxInitialSize
仅会影响初始加载 chunks。
boolean = false
function (module, chunks, cacheGroupKey) => string
string
每个 cacheGroup 也可以使用:splitChunks.cacheGroups.{cacheGroup}.name
。
拆分 chunk 的名称。设为 false
将保持 chunk 的相同名称,因此不会不必要地更改名称。这是生产环境下构建的建议值。
提供字符串或函数使你可以使用自定义名称。指定字符串或始终返回相同字符串的函数会将所有常见模块和 vendor 合并为一个 chunk。这可能会导致更大的初始下载量并减慢页面加载速度。
如果你选择指定一个函数,则可能会发现 chunk.name
和 chunk.hash
属性(其中 chunk
是 chunks
数组的一个元素)在选择 chunk 名时特别有用。
如果 splitChunks.name
与 entry point 名称匹配,entry point 将被删除。
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',
},
},
},
},
};
使用以下 splitChunks
配置来运行 webpack 也会输出一组公用组,其下一个名称为:commons-main-lodash.js.e7519d2bb8777058fa27.js
(以哈希方式作为真实世界输出示例)。
splitChunks.cacheGroups{cacheGroup}.usedExports
boolean = true
弄清哪些 export 被模块使用,以混淆 export 名称,省略未使用的 export,并生成有效的代码。
当它为 true
时:分析每个运行时使用的出口,当它为 "global"
时:分析所有运行时的全局 export 组合)。
缓存组可以继承和/或覆盖来自 splitChunks.*
的任何选项。但是 test
、priority
和 reuseExistingChunk
只能在缓存组级别上进行配置。将它们设置为 false
以禁用任何默认缓存组。
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
default: false,
},
},
},
};
splitChunks.cacheGroups.{cacheGroup}.priority
number = -20
一个模块可以属于多个缓存组。优化将优先考虑具有更高 priority
(优先级)的缓存组。默认组的优先级为负,以允许自定义组获得更高的优先级(自定义组的默认值为 0
)。
splitChunks.cacheGroups.{cacheGroup}.reuseExistingChunk
boolean = true
如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块。这可能会影响 chunk 的结果文件名。
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
reuseExistingChunk: true,
},
},
},
},
};
splitChunks.cacheGroups.{cacheGroup}.type
function
RegExp
string
允许按模块类型将模块分配给缓存组。
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
json: {
type: 'json',
},
},
},
},
};
splitChunks.cacheGroups.{cacheGroup}.test
function (module, { chunkGraph, moduleGraph }) => boolean
RegExp
string
控制此缓存组选择的模块。省略它会选择所有模块。它可以匹配绝对模块资源路径或 chunk 名称。匹配 chunk 名称时,将选择 chunk 中的所有模块。
为 {cacheGroup}.test
提供一个函数:
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
svgGroup: {
test(module) {
// `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) {
return module.type === 'javascript/auto';
},
},
},
},
},
};
为了查看 module
and chunks
对象中可用的信息,你可以在回调函数中放入 debugger;
语句。然后 以调试模式运行 webpack 构建 检查 Chromium DevTools 中的参数。
向 {cacheGroup}.test
提供 RegExp
:
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}.filename
string
function (pathData, assetInfo) => string
仅在初始 chunk 时才允许覆盖文件名。
也可以在 output.filename
中使用所有占位符。
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
filename: '[name].bundle.js',
},
},
},
},
};
若为函数,则:
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`;
},
},
},
},
},
};
通过提供以文件名开头的路径 'js/vendor/bundle.js'
,可以创建文件夹结构。
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
filename: 'js/[name]/bundle.js',
},
},
},
},
};
splitChunks.cacheGroups.{cacheGroup}.enforce
boolean = false
告诉 webpack 忽略 splitChunks.minSize
、splitChunks.minChunks
、splitChunks.maxAsyncRequests
和 splitChunks.maxInitialRequests
选项,并始终为此缓存组创建 chunk。
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
enforce: true,
},
},
},
},
};
splitChunks.cacheGroups.{cacheGroup}.idHint
string
设置 chunk id 的提示。 它将被添加到 chunk 的文件名中。
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
idHint: 'vendors',
},
},
},
},
};
// index.js
import('./a'); // dynamic import
// a.js
import 'react';
//...
结果: 将创建一个单独的包含 react
的 chunk。在导入调用中,此 chunk 并行加载到包含 ./a
的原始 chunk 中。
为什么:
node_modules
的模块react
大于 30kb这背后的原因是什么?react
可能不会像你的应用程序代码那样频繁地更改。通过将其移动到单独的 chunk 中,可以将该 chunk 与应用程序代码分开进行缓存(假设你使用的是 chunkhash,records,Cache-Control 或其他长期缓存方法)。
// 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
//...
结果: 将创建一个单独的 chunk,其中包含 ./helpers
及其所有依赖项。在导入调用时,此 chunk 与原始 chunks 并行加载。
为什么:
helpers
大于 30kb将 helpers
的内容放入每个 chunk 中将导致其代码被下载两次。通过使用单独的块,这只会发生一次。我们会进行额外的请求,这可以视为一种折衷。这就是为什么最小体积为 30kb 的原因。
创建一个 commons
chunk,其中包括入口(entry points)之间所有共享的代码。
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
commons: {
name: 'commons',
chunks: 'initial',
minChunks: 2,
},
},
},
},
};
创建一个 vendors
chunk,其中包括整个应用程序中 node_modules
的所有代码。
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
};
创建一个 custom vendor
chunk,其中包含与 RegExp
匹配的某些 node_modules
包。
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
name: 'vendor',
chunks: 'all',
},
},
},
},
};
stylelint-webpack-plugin 3.0 仅支持 webpack 5。对于 webpack 4,请查看 2.x 分支。
该插件使用 stylelint
帮助你在样式代码中避免错误并强制规范。
首先,你需要安装 stylelint-webpack-plugin
:
npm install stylelint-webpack-plugin --save-dev
注意:如果你还没有安装 stylelint >= 13
,请先用 npm 进行安装:
npm install stylelint --save-dev
然后添加该插件到你的 webpack 配置中。例如:
const StylelintPlugin = require('stylelint-webpack-plugin');
module.exports = {
// ...
plugins: [new StylelintPlugin(options)],
// ...
};
有关可用选项的完整列表请参阅 styleint 的配置项,这些选项直接传递给 stylelint
。
configFile
String
undefined
指定 stylelint
配置文件的位置。
注意: 默认情况下由 stylelint
处理。
context
String
compiler.context
指定文件根目录的字符串。
exclude
String|Array[String]
['node_modules', compiler.options.output.path]
指定要忽略的文件或目录。必须相对于 options.context
。
extensions
String|Array[String]
['css', 'scss', 'sass']
指定要检查的扩展名。
files
String|Array[String]
'**/*.(s(c|a)ss|css)'
可指定为目录,文件名或 globs。目录会递归地寻找与 options.extensions
相匹配的文件。文件名和 glob 模式将忽略 options.extensions
。
fix
Boolean
false
如果值为 true
,stylelint
将修复尽可能多的 error。修复真实的源文件。报告所有未修复的 errors。请参阅 自动修复错误 文档。
formatter
String|Function
'string'
指定要用于格式化结果的 formatter。请参阅 formatter 选项。
lintDirtyModulesOnly
Boolean
false
仅检查有变化的文件,启动时跳过检查。
stylelintPath
String
stylelint
将要用来做检查的 stylelint
实例的路径。
threads
Boolean | Number
false
设置为 true
时,会根据 cpu 的数量自动决定池子的大小。设置为大于 1 的数字时,可以确定池子的大小。设置为 false
、1 或更小时,会禁用池子,并只在主线程运行。
默认情况下,插件将根据 stylelint 错误/警告数量自动调整错误报告。
你仍然可以使用 emitError
或 emitWarning
选项来强制改变这种默认行为。
emitError
Boolean
true
如遇到错误将会被直接输出,如需禁用,请设置为 false
。
emitWarning
Boolean
true
如遇到警告将会被直接输出,如需禁用,请设置为 false
。
failOnError
Boolean
true
如果有任何错误,都将导致模块构建失败,如需禁用,请设置为 false
。
failOnWarning
Boolean
false
如果设置为 true
,出现任何 warnings 都将会导致模块构建失败。
quiet
Boolean
false
如果设置为 true
,则仅处理和报告 errors,并忽略 warnings。
outputReport
Boolean|Object
false
将输出的错误写入文件,例如,用于上报的 json
文件。
其 filePath
会相对于 webpack 配置中的:output.path
.
你可以为输出文件设置不同的 formatter
,如果未设置,则将使用默认 formatter
。
{
'path/to/file';
'json';
}
免责声明:TerserWebpackPlugin 是由社区成员维护的第三方包,它可能没有与 webpack 相同的支持、安全策略或许可证,并且它不是由 webpack 维护的。
该插件使用 terser 来压缩 JavaScript。
webpack v5 开箱即带有最新版本的 terser-webpack-plugin
。如果你使用的是 webpack v5 或更高版本,同时希望自定义配置,那么仍需要安装 terser-webpack-plugin
。如果使用 webpack v4,则必须安装 terser-webpack-plugin
v4 的版本。
首先需要安装 terser-webpack-plugin
:
npm install terser-webpack-plugin --save-dev
然后将插件添加到 webpack
配置文件中,例如:
webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
};
接下来,按照你习惯的方式运行 webpack
。
只对 devtool
选项的 source-map
,inline-source-map
,hidden-source-map
和 nosources-source-map
有效。
为何如此?
eval
通过 eval("string")
包裹模块而压缩工具不会处理字符串。cheap
不存在列信息而压缩工具输出的文件为单行文件,只会留下一个映射。使用支持的 devtool
值可以生成 source map。
test
类型: String|RegExp|Array<String|RegExp>
默认值:/\.m?js(\?.*)?$/i
用来匹配需要压缩的文件。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
}),
],
},
};
include
类型: String|RegExp|Array<String|RegExp>
默认值: undefined
匹配参与压缩的文件。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
include: /\/includes/,
}),
],
},
};
exclude
类型: String|RegExp|Array<String|RegExp>
默认值: undefined
匹配不需要压缩的文件。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
exclude: /\/excludes/,
}),
],
},
};
parallel
类型: Boolean|Number
默认值: true
使用多进程并发运行以提高构建速度。
并发运行的默认数量: os.cpus().length - 1
。
并发运行可以显著提高构建速度,因此强烈建议添加此配置 。
如果你使用 Circle CI 或任何其他不提供 CPU 实际可用数量的环境,则需要显式设置 CPU 数量,以避免
Error: Call retries were exceeded
(请参阅 #143,#202 )。
Boolean
启用/禁用多进程并发运行功能。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
};
Number
启用多进程并发运行并设置并发运行次数。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: 4,
}),
],
},
};
minify
类型: Function
默认值: TerserPlugin.terserMinify
允许你自定义压缩函数。 默认情况下,插件使用 terser 库。 对于使用和测试未发布的版本或 fork 的代码很帮助。
⚠️ 启用
parallel
选项时,在minify
函数内部只能使用require
。
webpack.config.js
// Can be async
const minify = (input, sourceMap, minimizerOptions, extractsComments) => {
// The `minimizerOptions` option contains option from the `terserOptions` option
// You can use `minimizerOptions.myCustomOption`
// Custom logic for extract comments
const { map, code } = require('uglify-module') // Or require('./path/to/uglify-module')
.minify(input, {
/* Your options for minification */
});
return { map, code, warnings: [], errors: [], extractedComments: [] };
};
// Used to regenerate `fullhash`/`chunkhash` between different implementation
// Example: you fix a bug in custom minimizer/custom function, but unfortunately webpack doesn't know about it, so you will get the same fullhash/chunkhash
// to avoid this you can provide version of your custom minimizer
// You don't need if you use only `contenthash`
minify.getMinimizerVersion = () => {
let packageJson;
try {
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
packageJson = require('uglify-module/package.json');
} catch (error) {
// Ignore
}
return packageJson && packageJson.version;
};
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
myCustomOption: true,
},
minify,
}),
],
},
};
terserOptions
类型: Object
默认值: 默认
Terser 配置项 。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
ecma: undefined,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
module: false,
// Deprecated
output: null,
format: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false,
},
}),
],
},
};
extractComments
类型: Boolean|String|RegExp|Function<(node, comment) -> Boolean|Object>|Object
默认值: true
是否将注释剥离到单独的文件中(请参阅详细信息)。
默认情况下,仅剥离 /^\**!|@preserve|@license|@cc_on/i
正则表达式匹配的注释,其余注释会删除。
如果原始文件名为 foo.js
,则注释将存储到 foo.js.LICENSE.txt
。
terserOptions.format.comments
选项指定是否保留注释,即可以在剥离其他注释时保留一些注释,甚至保留已剥离的注释。
Boolean
启用/禁用剥离注释功能。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
}),
],
},
};
String
剥离 all
或 some
(使用 /^\**!|@preserve|@license|@cc_on/i
正则表达式进行匹配)注释。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: 'all',
}),
],
},
};
RegExp
与指定表达式匹配的所有注释将会被剥离到单独的文件中。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: /@extract/i,
}),
],
},
};
Function<(node, comment) -> Boolean>
与指定表达式匹配的所有注释将会被剥离到单独的文件中。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: (astNode, comment) => {
if (/@extract/i.test(comment.value)) {
return true;
}
return false;
},
}),
],
},
};
Object
允许自定义剥离注释的条件,指定剥离的文件名和标题。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
condition
类型: Boolean|String|RegExp|Function<(node, comment) -> Boolean|Object>
自定义需要剥离的注释。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: 'some',
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
filename
类型: String|Function<(string) -> String>
默认值: [file].LICENSE.txt [query]
可用的占位符: [file]
, [query]
和 [filebase]
(webpack 5 使用 [base]
)。
剥离出来的注释将被存储到的文件的文件名。
默认是将后缀 .LICENSE.txt
附加到原始文件名。
⚠️ 我们强烈建议使用
txt
扩展名。 使用js
/cjs
/mjs
扩展名可能会与现有资源文件冲突,从而导致代码运行出错。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: 'extracted-comments.js',
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
banner
类型: Boolean|String|Function<(string) -> String>
默认值: /*! For license information please see ${commentsFile} */
指向剥离文件的标语文本将被添加到原始文件的顶部。
可以为 false
(无标题), String
或一个函数:Function<(string) -> String>
,该函数将被使用存储剥离的注释的文件名来调用。
标语内容将被合并到注释中。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: true,
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (commentsFile) => {
return `My custom banner about license information ${commentsFile}`;
},
},
}),
],
},
};
剥离所有有效的注释(即 /^\**!|@preserve|@license|@cc_on/i
)并保留 /@license/i
注释。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: /@license/i,
},
},
extractComments: true,
}),
],
},
};
如果要在构建时去除注释,请使用以下配置:
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: false,
},
},
extractComments: false,
}),
],
},
};
uglify-js
UglifyJS
是一款集 JavaScript 解析器,压缩器,美化器于一身的工具集。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.uglifyJsMinify,
// `terserOptions` options will be passed to `uglify-js`
// Link to options - https://github.com/mishoo/UglifyJS#minify-options
terserOptions: {},
}),
],
},
};
swc
swc
是一款采用 rust 编写的超快编译器;可以将最新标准和 TypeScript 的语法生成被广泛使用的 JavaScript。
⚠
extractComments
选项暂不支持,所有注释将默认被删除,会在将来得到修复。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.swcMinify,
// `terserOptions` options will be passed to `swc` (`@swc/core`)
// Link to options - https://swc.rs/docs/config-js-minify
terserOptions: {},
}),
],
},
};
esbuild
esbuild
是一款非常快速的 JavaScript 打包工具和压缩工具。
⚠ 不支持
extractComments
选项,所有法律相关的注释(如版权,许可证等)将被保留。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.esbuildMinify,
// `terserOptions` options will be passed to `esbuild`
// Link to options - https://esbuild.github.io/api/#minify
// Note: the `minify` options is true by default (and override other `minify*` options), so if you want to disable the `minifyIdentifiers` option (or other `minify*` options) please use:
// terserOptions: {
// minify: false,
// minifyWhitespace: true,
// minifyIdentifiers: false,
// minifySyntax: true,
// },
terserOptions: {},
}),
],
},
};
覆盖默认的 minify 函数 - 使用 uglify-js
进行压缩。
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: (file, sourceMap) => {
// https://github.com/mishoo/UglifyJS2#minify-options
const uglifyJsOptions = {
/* your `uglify-js` package options */
};
if (sourceMap) {
uglifyJsOptions.sourceMap = {
content: sourceMap,
};
}
return require('uglify-js').minify(file, uglifyJsOptions);
},
}),
],
},
};
使用默认 terser 压缩函数:
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: true,
},
}),
],
},
};
使用内置压缩函数:
import type { JsMinifyOptions as SwcOptions } from '@swc/core';
import type { MinifyOptions as UglifyJSOptions } from 'uglify-js';
import type { TransformOptions as EsbuildOptions } from 'esbuild';
import type { MinifyOptions as TerserOptions } from 'terser';
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin<SwcOptions>({
minify: TerserPlugin.swcMinify,
terserOptions: {
// `swc` options
},
}),
new TerserPlugin<UglifyJSOptions>({
minify: TerserPlugin.uglifyJsMinify,
terserOptions: {
// `uglif-js` options
},
}),
new TerserPlugin<EsbuildOptions>({
minify: TerserPlugin.esbuildMinify,
terserOptions: {
// `esbuild` options
},
}),
// Alternative usage:
new TerserPlugin<TerserOptions>({
minify: TerserPlugin.terserMinify,
terserOptions: {
// `terser` options
},
}),
],
},
};
请花一点时间阅读我们的贡献指南。
Ignore the specified files, i.e. those matching the provided paths or regular expressions, while in watch mode.
new webpack.WatchIgnorePlugin({ paths });
paths
(Array<string | RegExp>
): A list of RegExps or absolute paths to directories or files that should be ignored.