AutomaticPrefetchPlugin은 변경사항을 관찰하는 동안 이전 컴파일의 모든 모듈을 미리 검색하여 증가하는 빌드 시간을 개선합니다. 단일 모듈을 미리 검색하는 PrefetchPlugin 과 비교해보세요.
webpack.config.js
module.exports = {
// ...
plugins: [new webpack.AutomaticPrefetchPlugin()],
};
생성된 각 청크의 상단에 배너를 추가합니다.
const webpack = require('webpack');
new webpack.BannerPlugin(banner);
// 또는
new webpack.BannerPlugin(options);
{
banner: string | function, // 배너를 문자열 또는 함수로 사용하면, 주석으로 감싸집니다.
raw: boolean, // true이면, 배너가 주석에 감싸지지 않습니다.
entryOnly: boolean, // true이면, 배너는 엔트리 청크에만 추가됩니다.
test: string | RegExp | [string, RegExp], // 테스트를 통과하는 모든 모듈이 포함됩니다.
include: string | RegExp | [string, RegExp], // 다음 조건 중 하나라도 일치하는 모든 모듈이 포함됩니다.
exclude: string | RegExp | [string, RegExp], // 다음 조건 중 하나라도 일치하는 모든 모듈이 제외됩니다.
footer?: boolean, // true이면, 배너는 컴파일이 끝날 때 배치됩니다.
stage?: number, // 배너를 주입해야 하는 컴파일 단계
}
import webpack from 'webpack';
// 문자열
new webpack.BannerPlugin({
banner: 'hello world',
});
// 함수
new webpack.BannerPlugin({
banner: (yourVariable) => {
return `yourVariable: ${yourVariable}`;
},
});
// 최소화 및 애셋 조작 후 배너 메시지를 추가합니다.
new webpack.BannerPlugin({
raw: true,
banner: '/* 배너는 문자열입니다 */',
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT,
});
webpack 2.5.0 부터, placeholder는 배너 문자열로 평가됩니다.
import webpack from 'webpack';
new webpack.BannerPlugin({
banner:
'fullhash:[fullhash], chunkhash:[chunkhash], name:[name], filebase:[filebase], query:[query], file:[file]',
});
The chunks-webpack-plugin creates HTML files with entry points and chunks relations to serve your webpack bundles. It is suitable with multi-page applications that contain multiple entry points.
Since webpack 4, SplitChunksPlugin offers the possibility to optimizes all chunks. It can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks. See the webpack documentation of splitChunks.chunks for details.
splitChunks.chunks option can be set to automatically generate new chunks associated with an entry point. For example, entry points a.js and b.js share common code with the file vendors~a~b.js.
With multiple entry points, it can be difficult to identify relation between the auto-generated chunks and entry points.
chunks-webpack-plugin parses the webpack compilation entry points to get all files associated with the entry points. Then, it generates HTML files which include all assets filtered by an entry point and thechunks-manifest.json file.
It works without configuration. For advanced usage, see the using configuration section.
chunks-webpack-plugin is available on npm as chunks-webpack-plugin and as chunks-webpack-plugin on GitHub.
npm install chunks-webpack-plugin --save-dev
yarn add chunks-webpack-plugin --dev
[!WARNING] Plugin
chunks-webpack-plugin@10is ESM only. [!NOTE] Minimum supportedNode.jsversion is16.20.0and Webpack>=5.10.3.
The project includes a minimalist example in the ./example directory. Run the npm run build:example command to execute the Webpack example and see the plugin's implementation in action.
chunks-webpack-plugin will generate two HTML files for each entry point. Each filename contains the entry point name, the {{entry}} placeholder is automatically replaced.
{{entry}}-styles.html: contains all HTML <link> tags{{entry}}-scripts.html: contains all HTML <script> tagsFirst, let's add the plugin to the webpack configuration.
webpack.config.js
import ChunksWebpackPlugin from 'chunks-webpack-plugin';
export default {
plugins: [new ChunksWebpackPlugin()]
};
HTML files are built in the output path directory with the rest of the webpack compilation.
Now you can include the generated HTML files into your HTML page templates. You can do it with e.g. Twig.
main-styles.html
<link rel="stylesheet" href="main.css" />
main-scripts.html
<script defer src="main.js"></script>
You can pass a configuration object to chunks-webpack-plugin to override the default settings.
filenameType:
type filename = string;
Default: '[name]-[type].html'
Tells the plugin whether to personalize the filename of the generated files. Files are processed by the webpack compilation and generated in the output path directory. The placeholder [name] is automatically replaced by entry points names and [type] by styles|scripts.
new ChunksWebpackPlugin({
filename: 'templates/[name]-[type].html'
});
[!NOTE] The
filenamecan contain directories, which will be created automatically.
templateStyleType:
type templateStyle = (name: string, entryName: string) => string;
Default:
(name) => `<link rel="stylesheet" href="${name}" />`;
Tells the plugin whether to personalize the default template for the HTML <style> tags. For example, add additional attributes or a CDN prefix.
export default {
plugins: [
new ChunksWebpackPlugin({
templateStyle: (name) => `<link rel="stylesheet" href="https://cdn.domain.com${name}" />`
})
]
};
templateScriptType:
type templateScript = (name: string, entryName: string) => string;
Default:
(name) => `<script defer src="${name}"></script>`;
Tells the plugin whether to personalize the default template for the HTML <script> tags. For example, add additional attributes or a CDN prefix.
export default {
plugins: [
new ChunksWebpackPlugin({
templateScript: (name) => `<script defer src="https://cdn.domain.com${name}"></script>`
})
]
};
generateChunksManifestType:
type generateChunksManifest = boolean;
Default: false
Tells the plugin whether to generate the chunks-manifest.json. The file contains the list of all chunks grouped by entry points. See the chunks-manifest.json example.
export default {
plugins: [
new ChunksWebpackPlugin({
generateChunksManifest: true
})
]
};
generateChunksFilesType:
type generateChunksFiles = boolean;
Default: true
Tells the plugin whether to generate the HTML files.
export default {
plugins: [
new ChunksWebpackPlugin({
generateChunksFiles: false
})
]
};
[!WARNING] When set to
false, HTML files will not be generated. It can only be useful together withgenerateChunksManifestoption set totruefor custom generation of the HTML files.
Example of the webpack configuration with multiple entry points which share common code with the splitChunks option.
import ChunksWebpackPlugin from 'chunks-webpack-plugin';
import path from 'node:path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export default {
entry: {
home: 'home.js',
news: 'news.js'
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist')
},
plugins: [new ChunksWebpackPlugin()],
optimization: {
splitChunks: {
chunks: 'all'
}
}
};The plugin will generate all files in the output path directory:
home-styles.html
<link rel="stylesheet" href="vendors~home~news.css" />
<link rel="stylesheet" href="home.css" />home-scripts.html
<script defer src="vendors~home~news.js"></script>
<script defer src="home.js"></script>news-styles.html
<link rel="stylesheet" href="vendors~home~news.css" />
<link rel="stylesheet" href="news.css" />news-scripts.html
<script defer src="vendors~home~news.js"></script>
<script defer src="news.js"></script>chunks-webpack-plugin is licensed under the MIT License.
Created with ♥ by @yoriiis.
CommonsChunkPlugin은 여러 엔트리 포인트 간에 공유되는 공통 모듈로 이루어진 별도의 파일(청크라고 합니다)을 만드는 opt-in 기능입니다.
번들에서 공통 모듈을 분리한 결과로 생성된 청크 파일을 처음에 한 번 로드하고 나중에 사용하기 위해 캐시에 저장할 수 있습니다. 이로 인해 브라우저가 새 페이지를 방문할 때마다 더 큰 번들을 로드하지 않고 캐시에서 공유 코드를 빠르게 제공할 수 있으므로 페이지 속도가 최적화됩니다.
new webpack.optimize.CommonsChunkPlugin(options);
{
name: string, // 또는
names: string[],
// 공통 청크의 청크 이름입니다. 청크의 이름을 전달하여 기존 청크를 선택할 수 있습니다.
// 문자열 배열로 전달되면 각 청크 이름에 대해 플러그인을 여러 번 호출하는 것과 같습니다.
// 생략하면 `options.async` 또는 `options.children`이 설정되고 모든 청크가 사용됩니다.
// 그렇지 않으면 청크 이름으로 사용되는 `options.filename`이 사용되게 됩니다.
// `options.async`를 사용하여 다른 비동기 청크에서 공통 청크를 만들 때 `option.name`을 생략하는 대신 여기에
// 엔트리 포인트 청크 이름을 지정해야 합니다.
filename: string,
// 공통 청크의 파일 이름 템플릿입니다. `output.filename`과 동일한 플레이스홀더를 포함할 수 있습니다.
// 생략하면 원본 파일 이름은 수정되지 않습니다(일반적으로 `output.filename` 혹은 `output.chunkFilename`).
// 이 옵션은 `options.async`를 사용하는 경우에도 허용되지 않습니다. 자세한 내용은 아래를 참조하세요.
minChunks: number|Infinity|function(module, count) => boolean,
// 공통 청크로 이동하기 전에 모듈을 포함해야 하는 최소 청크 수입니다.
// 숫자는 2보다 크거나 같고 청크 수보다 작거나 같아야 합니다.
// `Infinity`를 전달하면 공통 청크가 생성되지만 모듈은 이동하지 않습니다.
// `function`을 제공하여 맞춤 로직을 추가 할 수 있습니다.(기본값은 청크의 수입니다)
chunks: string[],
// 청크 이름으로 소스 청크를 선택합니다. 청크는 공통 청크의 자식이어야 합니다.
// 생략하면 모든 엔트리 청크가 선택됩니다.
children: boolean,
// `true`이면 공통 청크의 모든 자식이 선택됩니다.
deepChildren: boolean,
// `true`이면 공통 청크의 모든 자손이 선택됩니다.
async: boolean|string,
// `true`이면 새로운 비동기 공통 청크가 `options.name`의 하위 항목 및 `options.chunks`와 동등한 항목으로 생성됩니다.
// `options.chunks`와 병렬로 로드됩니다.
// `option.filename`을 사용하는 대신 `true`가 아닌 원하는 문자열을 제공해
// 출력 파일의 이름을 변경할 수 있습니다.
minSize: number,
// 공통 청크가 생성되기 전 모든 공통 모듈의 최소 사이즈입니다.
}
엔트리 포인트 간에 공유되는 공통 모듈을 포함하는 추가 청크를 생성합니다.
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
// (공통 청크 이름)
filename: 'commons.js',
// (공통 청크의 파일 이름)
// minChunks: 3,
// (모듈은 최소 3개의 엔트리 사이에서 공유해야 합니다)
// chunks: ["pageA", "pageB"],
// (이 엔트리에서만 사용됩니다)
});
생성된 청크는 엔트리 포인트 전에 로드해야 합니다.
<script src="commons.js" charset="utf-8"></script>
<script src="entry.bundle.js" charset="utf-8"></script>
코드를 vendor와 애플리케이션으로 분할합니다.
module.exports = {
//...
entry: {
vendor: ['jquery', 'other-lib'],
app: './entry',
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
// filename: "vendor.js"
// (청크에 다른 이름을 지정하세요)
minChunks: Infinity,
// (엔트리가 더 많으면 다른 모듈이 vendor 청크로
// 들어가지 않습니다)
}),
],
};
<script src="vendor.js" charset="utf-8"></script>
<script src="app.js" charset="utf-8"></script>
Code Splitting을 사용하면 엔트리 청크의 여러 하위(자식) 청크가 공통 종속성을 가질 수 있습니다. 중복을 방지하기 위해 이들을 부모 청크로 옮길 수 있습니다. 이렇게 하면 전체 크기가 줄어들지만, 초기 로드 시간에 부정적인 영향을 미칩니다. 사용자가 많은 형제 청크(예: 엔트리 청크의 자식)를 다운로드해야 할 것으로 예상되는 경우 전체 로드 시간이 향상됩니다.
new webpack.optimize.CommonsChunkPlugin({
// names: ["app", "subPageA"]
// (청크를 선택하거나 모든 청크를 생략하세요)
children: true,
// (선택된 청크의 모든 자식을 선택합니다)
// minChunks: 3,
// (모듈을 옮기기 전에 3명의 자식이 공유해야 합니다)
});
위의 것과 유사하지만 공통 모듈을 부모로 이동하는 대신(초기 로드 시간을 증가시키게 됩니다) 비동기식으로 로드된 새로운 추가 공통 청크가 사용됩니다. 이는 추가 청크가 다운로드되면 자동으로 병렬로 다운로드됩니다.
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
// 또는
names: ['app', 'subPageA'],
// 단일 이름 또는 배열 형태의 이름은 비동기 청크를 생성하는
// 엔트리 포인트의 이름과 일치해야 합니다.
children: true,
// (청크의 모든 자식을 사용합니다)
async: true,
// (비동기 공통 청크를 생성합니다)
minChunks: 3,
// (모듈이 분리되기 전에 3명의 자식이 모듈을 공유해야 합니다)
});
minChunks property a function또한 minChunks 속성에 함수를 전달할 수도 있습니다. 이 함수는 CommonsChunkPlugin에 의해 호출되며 module 및 count 인수로 함수를 호출합니다.
module 인수는 name/names 속성을 통해 제공된 청크의 각 모듈을 나타냅니다.
module은 NormalModule의 형태로, 이 사용 사례에 특히 유용한 두 개의 속성이 있습니다.
module.context: 파일을 저장하는 디렉터리입니다. 예: '/my_project/node_modules/example-dependency'module.resource: 처리중인 파일의 이름입니다. 예: '/my_project/node_modules/example-dependency/index.js'count 인수는 module이 사용되는 청크 수를 나타냅니다.
이 옵션은 CommonsChunk 알고리즘을 통해 모듈을 이동할 위치를 결정하는 방법을 세밀하게 제어하려는 경우에 유용합니다.
new webpack.optimize.CommonsChunkPlugin({
name: 'my-single-lib-chunk',
filename: 'my-single-lib-chunk.js',
minChunks: function (module, count) {
// 모듈이 경로를 가지고 있고 경로에 "somelib"이 존재하고
// 3개의 개별 청크/엔트리에서 사용되는 경우
// 청크의 키 이름이 "my-single-lib-chunk", 파일 이름이 "my-single-lib-chunk.js"로 분할됩니다.
return module.resource && /somelib/.test(module.resource) && count === 3;
},
});
위에서 볼 수 있듯이 이 예제를 사용하면 함수 내의 모든 조건이 충족되는 경우에만, 하나의 라이브러리를 별도의 파일로 이동할 수 있습니다.
이 개념은 암시적 공통 vendor 청크를 얻는데 사용할 수 있습니다.
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
// 이는 vendor의 import가 node_modules 디렉터리에 존재한다고 가정합니다.
return module.context && module.context.includes('node_modules');
},
});
webpack 부트스트랩 로직을 별도의 파일로 추출하려면 entry로 정의되어 있지 않은 name에 CommonsChunkPlugin을 사용하세요. 자세한 내용은 캐싱 가이드를 참조하세요.
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity,
});
vendor와 manifest 청크는 minChunks에 대해 다른 정의를 사용하므로 플러그인을 두 번 호출해야 합니다.
[
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
or
yarn add -D compression-webpack-plugin
or
pnpm add -D compression-webpack-plugin
Then add the plugin to your webpack config. For example:
webpack.config.js
const CompressionPlugin = require("compression-webpack-plugin");
module.exports = {
plugins: [new CompressionPlugin()],
};
Finally, run webpack using the method you normally use (e.g., via CLI or an npm script).
testType:
type test = string | RegExp | (string | RegExp)[];
Default: undefined
Include all assets that pass test assertion.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
test: /\.js(\?.*)?$/i,
}),
],
};
includeType:
type include = string | RegExp | (string | RegExp)[];
Default: undefined
Include all assets matching any of these conditions.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
include: /\/includes/,
}),
],
};
excludeType:
type exclude = string | RegExp | (string | RegExp)[];
Default: undefined
Exclude all assets matching any of these conditions.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
exclude: /\/excludes/,
}),
],
};
algorithmType:
type algorithm =
| string
| ((
input: Buffer,
options: CompressionOptions,
callback: (
error: Error | null | undefined,
result:
| string
| ArrayBuffer
| SharedArrayBuffer
| Uint8Array
| readonly number[]
| {
valueOf(): ArrayBuffer | SharedArrayBuffer;
}
| {
valueOf(): string | Uint8Array | readonly number[];
}
| {
valueOf(): string;
}
| {
[Symbol.toPrimitive](hint:%20%22string%22): string;
},
) => void,
) => void);
Defines the compression algorithm or function to use. Defaults to gzip.
[!NOTE]
If you use a custom function for the
algorithmoption, the default value ofcompressionOptionswill be an empty object{}.
stringThe algorithm is based on the Node.js zlib module.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
algorithm: "gzip",
}),
],
};
functionAllow you to specify a custom compression function.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
algorithm(input, compressionOptions, callback) {
return compressionFunction(input, compressionOptions, callback);
},
}),
],
};
compressionOptionsType:
interface compressionOptions {
flush?: number;
finishFlush?: number;
chunkSize?: number;
windowBits?: number;
level?: number;
memLevel?: number;
strategy?: number;
dictionary?: Buffer | TypedArray | DataView | ArrayBuffer;
info?: boolean;
maxOutputLength?: number;
}
Default: { level: 9 }
Compression options for algorithm.
You can find all available options in the zlib documentation.
[!NOTE]
If you use a custom function for the
algorithmoption, the default value ofcompressionOptionswill be an empty object{}.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
compressionOptions: { level: 1 },
}),
],
};
thresholdType:
type threshold = number;
Default: 0
Only assets larger than this size (in bytes) are processed.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
threshold: 8192,
}),
],
};
minRatioType:
type minRatio = number;
Default: 0.8
Only assets that compress better than this ratio are processed (minRatio = Compressed Size / Original Size).
For example, if you have a image.png file with a size of 1024 bytes, and its compressed version is of 768 bytes, the minRatio is 0.75.
In other words, assets will be processed only when the ratio of Compressed Size / Original Size is less than the specified minRatio.
You can use a value of 1 to process assets that are smaller than or equal to the original size.
Use a value of Infinity to process all assets, even if they are larger than the original size or their original size is 0 bytes (useful when you are pre-zipping all assets for AWS).
Use a value of Number.MAX_SAFE_INTEGER to process all assets even if they are larger than the original size, excluding assets with their original size is 0 bytes.
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
// Compress all assets, including files with `0` bytes size
// minRatio: Infinity
// Compress all assets, excluding files with `0` bytes size
// minRatio: Number.MAX_SAFE_INTEGER
minRatio: 0.8,
}),
],
};
filenameType:
type filename = string | ((pathdata: PathData) => string);
Default: "[path][base].gz"
The target asset filename.
stringFor example, given an asset path: assets/images/image.png?foo=bar#hash:
[path] is replaced with the directories of the original asset, including the trailing / (assets/images/).
[file] is replaced with the path of the original asset (assets/images/image.png).
[base] is replaced with the base name ([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, including the . (.png).
[query] is replaced with the query of the original asset, including the ? (?foo=bar).
[fragment] is replaced with the fragment (in the concept of URL it is called hash) of the original asset (#hash).
webpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
filename: "[path][base].gz",
}),
],
};
functionwebpack.config.js
module.exports = {
plugins: [
new CompressionPlugin({
filename(pathData) {
// The `pathData` argument contains all placeholders - `path`/`name`/`ext`/etc
// Available properties described above, for the `String` notation
if (/\.svg$/.test(pathData.filename)) {
return "assets/svg/[path][base].gz";
}
return "assets/js/[path][base].gz";
},
}),
],
};
deleteOriginalAssetsType:
type deleteOriginalAssets =
| boolean
| "keep-source-map"
| ((name: string) => boolean);
Default: false
Determines whether the original (uncompressed) assets should be deleted after compression.
If set to true , all original assets will be deleted.
If set to "keep-source-map", all original assets except source maps (.map files) will be deleted.
If a function is provided, it will be called with each asset’s name and should return true to delete the asset or false to keep it.
Example:
module.exports = {
plugins: [
new CompressionPlugin({
deleteOriginalAssets: (assetName) =>
// Delete all assets except images
!assetName.endsWith(".png") && !assetName.endsWith(".jpg"),
}),
],
};
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",
}),
],
};
Using a custom function:
module.exports = {
plugins: [
new CompressionPlugin({
exclude: /.map$/,
deleteOriginalAssets: (name) => {
if (/\.js$/.test(name)) {
return false;
}
return true;
},
}),
],
};
Prepare compressed versions of assets using the zopfli library.
[!NOTE]
@gfx/zopflirequires at leastNode.jsversion8.
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.js v10.16.0 and later includes native support for Brotli compression in its zlib module.
You 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("node: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.
Zstandard (zstd) is a fast lossless compression algorithm, targeting real-time compression scenarios at zlib-level and better compression ratios.
Node.js 22.15.0 and later includes native support for Zstandard compression in its zlib module.
You can take advantage of this built-in support for zstd in Node 22.15.0 and later by just passing in the appropriate algorithm to the CompressionPlugin:
webpack.config.js
const zlib = require("node:zlib");
module.exports = {
plugins: [
new CompressionPlugin({
filename: "[path][base].zst",
algorithm: "zstdCompress",
test: /\.(js|css|html|svg)$/,
compressionOptions: {
params: {
[zlib.constants.ZSTD_c_compressionLevel]: 10,
},
},
threshold: 10240,
minRatio: 0.8,
deleteOriginalAssets: false,
}),
],
};
You can find all Zstandard's options in the relevant part of the zlib module documentation.
webpack.config.js
const zlib = require("node: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,
}),
],
};
We welcome contributions!
Please take a moment to read our contributing guidelines if you haven't yet done so.
컨텍스트 는 require('./locale/' + name + '.json')와 같은 표현식으로 구성된 요청을 의미합니다.
ContextExclusionPlugin을 사용하면 컨텍스트를 제외할 수 있습니다. 정규 표현식과 일치하는 모든 컨텍스트를 제외하려면 플러그인을 초기화할 때 정규 표현식을 인수로 제공하세요.
webpack.config.js
module.exports = {
plugins: [new webpack.ContextExclusionPlugin(/dont/)],
};
Context는 require('./locale/' + name + '.json')와 같은 표현식을 통한 요청을 나타냅니다. 이러한 표현식을 만나면, webpack은 디렉터리 ('./locale/')와 정규 표현식 (/^.*\.json$/)을 추론합니다. 컴파일 시 name을 알 수 없기 때문에 webpack은 모든 파일을 번들에 모듈로 포함합니다.
ContextReplacementPlugin을 사용하면 추론된 정보를 오버라이드 할 수 있습니다. 플러그인을 구성하는 방법에는 여러 가지가 있습니다.
new webpack.ContextReplacementPlugin(
resourceRegExp: RegExp,
newContentResource?: string,
newContentRecursive?: boolean,
newContentRegExp?: RegExp
)
리소스(디렉터리)가 resourceRegExp와 일치하면, 플러그인은 기본 리소스, 재귀 플래그 또는 생성된 정규식을 각각 newContentResource, newContentRecursive 또는 newContextRegExp로 바꿉니다. newContentResource가 상대적인 경우 이전 리소스를 기준으로 해결됩니다.
다음은 모듈 사용을 제한하는 작은 예제입니다.
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /de|fr|hu/);
moment/locale 컨텍스트는 /de|fr|hu/와 일치하는 파일로 제한됩니다. 따라서 해당 locale만 포함됩니다(자세한 내용은 이 이슈를 참고하세요).
new webpack.ContextReplacementPlugin(
resourceRegExp: RegExp,
newContentCallback: (data) => void
);
newContentCallback 함수에는 ContextModuleFactory의 data 객체가 제공되며 제공된 객체의 request 속성을 덮어쓸 것으로 예상됩니다.
이 콜백을 사용하여 요청을 새 위치로 동적 리다이렉션할 수 있습니다.
new webpack.ContextReplacementPlugin(/^\.\/locale$/, (context) => {
if (!/\/moment\//.test(context.context)) return;
Object.assign(context, {
regExp: /^\.\/\w+/,
request: '../../locale', // 상대적으로 해결
});
});
newContentResource 및 newContentCreateContextMap 파라미터도 사용할 수 있습니다.
new webpack.ContextReplacementPlugin(
resourceRegExp: RegExp,
newContentResource: string,
newContentCreateContextMap: object // 런타임-요청(userRequest)을 컴파일-시간-요청(request)으로 매핑
);
이 두 파라미터를 함께 사용하여 보다 대상화된 방식으로 요청을 리다이렉션할 수 있습니다. newContentCreateContextMap을 사용하면 런타임 요청을 매핑하여 객체 형태로 요청을 컴파일 할 수 있습니다.
new ContextReplacementPlugin(/selector/, './folder', {
'./request': './request',
'./other-request': './new-request',
});
Copies existing individual files or entire directories to the build directory.
To begin, you'll need to install copy-webpack-plugin:
npm install copy-webpack-plugin --save-dev
or
yarn add -D copy-webpack-plugin
or
pnpm add -D copy-webpack-plugin
Then add the plugin to your webpack configuration. 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" },
],
}),
],
};
[!NOTE]
copy-webpack-pluginis not designed to copy files generated during the build process. Instead, it is meant to copy files that already exist in the source tree, as part of the build process.
[!NOTE]
If you want
webpack-dev-serverto write files to the output directory during development, you can enable thewriteToDiskoption or use thewrite-file-webpack-plugin.
[!NOTE]
You can get the original source filename from the Asset Objects in the webpack stats API.
The plugin's usage:
webpack.config.js
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: "source", to: "dest" },
"path/to/source", // Absolute or relative path, can be files, directories or globs. See examples below.
],
options: {
concurrency: 100,
},
}),
],
};
PatternsfromtocontextglobOptionsfiltertoTypeforceprioritytransformtransformAllnoErrorOnMissinginfofromType:
type from = string;
Default: undefined
Glob or path from where we copy files.
Globs follow the fast-glob pattern-syntax.
Note: Globs must be a string.
[!WARNING]
Don't use directly
\\infromoption if it is aglob(i.epath\to\file.ext) option, as backslashes are treated as regular characters on UNIX systems(not as path separators). On Windows, both forward slashes and backslashes act as separators. Use/instead, or use Node'spathutilities to normalize paths.
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").replaceAll("\\", "/"),
"*.txt",
),
],
}),
],
};
For windowsIf you're using an absolute file or folder path in the from option on Windows, you can use windows path segment (\\)
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, "file.txt"),
},
],
}),
],
};
However, when writing glob expressions, always use forward slashes.
See the fast-glob manual for more details.
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").replaceAll("\\", "/"),
"*.txt",
),
},
],
}),
],
};
The behavior of the context option varies depending on whether the from value is a glob, file or dir.
See more examples.
toType:
type to =
| string
| ((pathData: { context: string; absoluteFilename?: string }) => string);
Default: compiler.options.output
stringSpecifies the output path.
[!WARNING]
Don't use directly
\\in thetopath (i.epath\to\dest) option, as backslashes are treated as regular characters on UNIX systems(not as path separators). On Windows, both forward slashes and backslashes act as separators. Use/instead, or use Node'spathutilities to normalize paths.
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]",
},
],
}),
],
};
functionAllows to modify the writing path.
[!WARNING]
Don't use directly
\\into(i.epath\to\newFile) option, as backslashes are treated as regular characters on UNIX systems(not as path separators). On Windows, both forward slashes and backslashes act as separators. Use/instead, or use Node'spathutilities to normalize paths.
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]");
},
},
],
}),
],
};
contextType:
type context = string;
Default: options.context|compiler.options.context
Defines the base directory used for two purposes:
It is prepended to the from path.
It is removed from the beginning of the result path(s).
[!WARNING]
Don't use directly
\\into(i.epath\to\newFile) option, as backslashes are treated as regular characters on UNIX systems(not as path separators). On Windows, both forward slashes and backslashes act as separators. Use/instead, or use Node'spathutilities to normalize paths.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/*.txt",
to: "dest/",
context: "app/",
},
],
}),
],
};
The context can be an absolute or relative path. If it's relative, then it will be converted to an absolute path based on compiler.options.context.
You should explicitly define context when from uses a glob pattern. Otherwise, the plugin sets it automatically based on the nature of from:
If from is a file, then context defaults to the file’s directory. The result path will be just the filename alone.
If from is a directory, context is set to the same directory. The result paths include the directory’s contents (including subdirectories), relative to it.
The use of context is illustrated by these examples.
globOptions[!WARNING]
The onlyDirectories does not work because the plugin is designed to copy files, not directories alone.
Type:
type globOptions = import("tinyglobby").GlobOptions;
Default: undefined
Allows you to configure the glob pattern matching library used by the plugin. See the list of supported options To exclude files from being copied, use the globOptions.ignore option
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "public/**/*",
globOptions: {
dot: true,
gitignore: true,
ignore: ["**/file.*", "**/ignored-directory/**"],
},
},
],
}),
],
};
filterType:
type filter = (filepath: string) => boolean;
Default: undefined
[!NOTE]
To ignore files by path (e.g., by extension or name), prefer using the [
globOptions.ignore] option.
webpack.config.js
const fs = require("node:fs").promise;
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "public/**/*",
filter: async (resourcePath) => {
const data = await fs.promises.readFile(resourcePath);
const content = data.toString();
if (content === "my-custom-content") {
return false;
}
return true;
},
},
],
}),
],
};
toTypeType:
type toType = "dir" | "file" | "template";
Default: undefined
Determines the type of the to option — whether it's a 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 should explicitly set the type to dir.
In most cases, the plugin will automatically determine the correct type, so you typically don't need to set this option manually.
| Name | Type | Default | Description |
|---|---|---|---|
'dir' | string | undefined | Used to has no extension or ends with a '/'. |
'file' | string | undefined | Used when to is a file path that is not a directory or template. |
'template' | string | undefined | Used when 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",
},
],
}),
],
};
forceType:
type force = boolean;
Default: false
Overwrites files that already exist in compilation.assets (typically added by other plugins or loaders).
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/**/*",
to: "dest/",
force: true,
},
],
}),
],
};
priorityType:
type priority = 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 enable overwriting, the force option must be set to true.
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,
},
],
}),
],
};
transformType:
type transform =
| {
transformer: (input: string, absoluteFilename: string) => string | Buffer;
cache?: boolean | TransformerCacheObject | undefined;
}
| ((input: string, absoluteFilename: string) => string | Buffer);
Default: undefined
Allows you to modify the contents of a file before it is written to the output directory.
functionwebpack.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 | Default | Description |
|---|---|---|
transformer | undefined | Allows you to modify the contents of the file. |
cache | false | Enables caching for transform. You can use transform: { cache: { key: 'my-cache-key' } } to manually invalidate the cache when needed. |
transformerType:
type transformer = (input: string, absoluteFilename: string) => string;
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));
},
},
},
],
}),
],
};
cacheType:
type cache =
| boolean
| {
keys: Record<string, any>;
}
| {
keys: (
defaultCacheKeys: Record<string, any>,
absoluteFilename: string,
) => Promise<Record<string, any>>;
}
| undefined;
Default: false
webpack.config.js
Enable or disable caching and configure its behavior.
By default, the cache directory is located at: node_modules/.cache/copy-webpack-plugin.
booleanEnables/Disable transform caching.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/*.png",
to: "dest/",
transform: {
transformer(content, path) {
return optimize(content);
},
cache: true,
},
},
],
}),
],
};
objectEnables transform caching and setup invalidation keys.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/*.png",
to: "dest/",
transform: {
transformer(content, path) {
return optimize(content);
},
cache: {
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: {
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: {
keys: async (defaultCacheKeys, absoluteFrom) => {
const keys = await getCustomCacheInvalidationKeysAsync();
return {
...defaultCacheKeys,
keys,
};
},
},
},
},
],
}),
],
};
transformAllType:
type transformAll = (
data: {
data: Buffer;
sourceFilename: string;
absoluteFilename: string;
}[],
) => string[];
Default: undefined
Allows you to modify the contents of multiple files and save the combined result into a single file.
[!NOTE]
The
tooption must be specified and point to a file. Only the[contenthash]and[fullhash]template strings are allowed in the filename.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: "src/**/*.txt",
to: "dest/file.txt",
// The `assets` argument is an array of assets matched by the pattern `from` ("src/**/*.txt")
transformAll(assets) {
const result = assets.reduce((accumulator, asset) => {
// The asset content can be obtained from `asset.source` using `source` method.
// The asset content is a [`Buffer`](https://nodejs.org/api/buffer.html) object, it could be converted to a `String` to be processed using `content.toString()`
const content = asset.data;
accumulator = `${accumulator}${content}\n`;
return accumulator;
}, "");
return result;
},
},
],
}),
],
};
noErrorOnMissingType:
type noErrorOnMissing = boolean;
Default: false
Doesn't generate an error if file(s) are missing.
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, "missing-file.txt"),
noErrorOnMissing: true,
},
],
}),
],
};
infoType:
type info =
| Record<string, any>
| ((item: {
absoluteFilename: string;
sourceFilename: string;
filename: string;
toType: ToType;
}) => Record<string, any>);
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 minification
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 }),
},
],
}),
],
};
concurrencytype:
type concurrency = number;
Default: 100
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).Consider 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 don't want the result paths to start with src/directory-nested/, then you should move src/directory-nested/ to context, such that only the glob pattern **/* remains in from:
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 equivalent to using **/* with a predefined context set 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 the file's directory 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").replaceAll("\\", "/"),
"**/*",
),
globOptions: {
ignore: [
// Ignore all `txt` files
"**/*.txt",
// Ignore all files in all subdirectories
"**/subdir/**",
],
},
},
],
}),
],
};
Removes all directory references and copies only file names.
[!WARNING]
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 monoreposWhen using yarn workspaces or monorepos, relative copy paths from node_modules can be broken due to the way packages are hoisting.
To avoid this, you should explicitly specify where to copy the files from; by using require.resolve.
webpack.config.js
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{
from: `${path.dirname(
require.resolve(`${moduleName}/package.json`),
)}/target`,
to: "target",
},
],
}),
],
};
We welcome all contributions!
If you are new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.
This plugin uses cssnano to optimize and minify your CSS.
It serves as a more accurate alternative to optimize-css-assets-webpack-plugin, with better support for source maps, assets with query strings, caching, and parallel processing.
To begin, you'll need to install css-minimizer-webpack-plugin:
npm install css-minimizer-webpack-plugin --save-dev
or
yarn add -D css-minimizer-webpack-plugin
or
pnpm add -D css-minimizer-webpack-plugin
Then add the plugin to your webpack configuration. For example:
webpack.config.js
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
module: {
rules: [
{
test: /\.s?css$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
},
],
},
optimization: {
minimizer: [
// For webpack v5, you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line // `...`,
new CssMinimizerPlugin(),
],
},
plugins: [new MiniCssExtractPlugin()],
};
[!NOTE]
This enables CSS optimization only in production mode by default.
To enable it in development mode as well, set the optimization.minimize option to true:
webpack.config.js
// [...]
module.exports = {
optimization: {
// [...]
minimize: true,
},
};
Finally, run Webpack using your preferred method.
This plugin works only with source-map, inline-source-map, hidden-source-map and nosources-source-map values for the devtool option.
Why? Because CSS support only these source map types.
The plugin respects the devtool setting and uses the SourceMapDevToolPlugin internally.
Using a supported devtool value enables source map generation.
Enabling the columns option in SourceMapDevToolPlugin also allows source map generation.
Use source maps to map error message locations to their original modules (note that this may slow down compilation).
If you use your own minify function please refer to the minify section for correct handling of source maps.
| Name | Type | Default | Description |
|---|---|---|---|
test | String|RegExp|Array<String|RegExp> | /\.css(\?.*)?$/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 | Enable or disable multi-process parallel running. |
minify | Function|Array<Function> | CssMinimizerPlugin.cssnanoMinify | Allows to override default minify function. |
minimizerOptions | Object|Array<Object> | { preset: 'default' } | Cssnano optimisations options. |
warningsFilter | Function<(warning, file, source) -> Boolean> | () => true | Allows filtering of css-minimizer warnings. |
testString|RegExp|Array<String|RegExp>/\.css(\?.*)?$/iTest to match files against.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
test: /\.foo\.css$/i,
}),
],
},
};
includeString|RegExp|Array<String|RegExp>undefinedFiles to include.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
include: /\/includes/,
}),
],
},
};
excludeString|RegExp|Array<String|RegExp>undefinedFiles to exclude.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
exclude: /\/excludes/,
}),
],
},
};
parallelBoolean|NumbertrueUse multi-process parallel running to improve the build speed.
The default number of concurrent runs: os.cpus().length - 1 or os.availableParallelism() - 1 (if this function is supported).
ℹ️ Parallelization can speed up your build significantly and is therefore highly recommended. If a parallelization is enabled, the packages in
minimizerOptionsmust be required via strings (packageNameorrequire.resolve(packageName)). Read more inminimizerOptions
BooleanEnable or disable multi-process parallel running.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
parallel: true,
}),
],
},
};
NumberEnable multi-process parallel running and specify the number of concurrent runs.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
parallel: 4,
}),
],
},
};
minifyFunction|Array<Function>CssMinimizerPlugin.cssnanoMinifyOverrides the default minify function.
By default, plugin uses cssnano package.
This is useful when using or testing unpublished versions or forks.
Possible options:
CssMinimizerPlugin.cssnanoMinifyCssMinimizerPlugin.cssoMinifyCssMinimizerPlugin.cleanCssMinifyCssMinimizerPlugin.esbuildMinifyCssMinimizerPlugin.lightningCssMinify (previouslyCssMinimizerPlugin.parcelCssMinify, the package was renamed, but we keep it for backward compatibility)async (data, inputMap, minimizerOptions) => {return {code: "a{color: red}", map: "...", warnings: [], errors: []}}[!WARNING]
Always use
requireinsideminifyfunction whenparalleloption is enabled.
Functionwebpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
level: {
1: {
roundingPrecision: "all=3,px=5",
},
},
},
minify: CssMinimizerPlugin.cleanCssMinify,
}),
],
},
};
ArrayIf an array of functions is passed to the minify option, the minimizerOptions must also be an array.
The function index in the minify array corresponds to the options object with the same index in the minimizerOptions array.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: [
{}, // Options for the first function (CssMinimizerPlugin.cssnanoMinify)
{}, // Options for the second function (CssMinimizerPlugin.cleanCssMinify)
{}, // Options for the third function
],
minify: [
CssMinimizerPlugin.cssnanoMinify,
CssMinimizerPlugin.cleanCssMinify,
async (data, inputMap, minimizerOptions) =>
// Custom minifier function
({
code: "a{color: red}",
map: '{"version": "3", ...}',
warnings: [],
errors: [],
}),
],
}),
],
},
};
minimizerOptionsObject|Array<Object>{ preset: 'default' }Cssnano optimisations options.
Objectmodule.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
preset: [
"default",
{
discardComments: { removeAll: true },
},
],
},
}),
],
},
};
ArrayThe 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.
If parallelization is enabled, the packages in
minimizerOptionsmust be referenced via strings (packageNameorrequire.resolve(packageName)). In this case, we shouldn't userequire/import.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
preset: require.resolve("cssnano-preset-simple"),
},
}),
],
},
};
processorOptions (⚠ only cssnano)Object{ from: assetName }Allows filtering options processoptions for the cssnano.
The parser, stringifier and syntax can be either a function or a string indicating the module that will be imported.
[!WARNING]
If any of these options are passed as a function, the
paralleloption must be disabled..
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",
},
},
}),
],
},
};
warningsFilterFunction<(warning, file, source) -> Boolean>() => trueFilter css-minimizer warnings (By default cssnano).
Return true to keep the warning, or a falsy value (false/null/undefined) to suppress it.
[!WARNING]
The
sourceparameter will beundefinedunless source maps are enabled.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
warningsFilter: (warning, file, source) => {
if (/Dropping unreachable code/i.test(warning)) {
return true;
}
if (/file\.css/i.test(file)) {
return true;
}
if (/source\.css/i.test(source)) {
return true;
}
return false;
},
}),
],
},
};
Don't forget to enable sourceMap options for all loaders.
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
devtool: "source-map",
module: {
rules: [
{
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()],
};
Remove all comments, including those starting with /*!.
module.exports = {
optimization: {
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
preset: [
"default",
{
discardComments: { removeAll: true },
},
],
},
}),
],
},
};
webpack.config.js
module.exports = {
// Uncomment if you need source maps
// 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 = {
// Uncomment if you need source maps
// 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 = {
// Uncomment if you need source maps
// devtool: "source-map",
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minify: CssMinimizerPlugin.esbuildMinify,
}),
],
},
};
@parcel/csswebpack.config.js
module.exports = {
// devtool: "source-map", // Uncomment for source maps
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minify: CssMinimizerPlugin.lightningCssMinify,
// Uncomment this line for options
// minimizerOptions: { targets: { ie: 11 }, drafts: { nesting: true } },
}),
],
},
};
webpack.config.js
module.exports = {
// devtool: "source-map", // Uncomment for source maps
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
minify: CssMinimizerPlugin.swcMinify,
// Uncomment this line for options
// minimizerOptions: {},
}),
],
},
};
We welcome all contributions!
If you're new here, please take a moment to review our contributing guidelines.
DefinePlugin을 사용하면 컴파일 타임에 구성할 수 있는 전역 상수를 만들 수 있습니다. 이는 개발 빌드와 프로덕션 빌드 간에 서로 다른 동작을 하고 싶을 때 유용합니다. 개발 빌드에서 로깅을 수행하지만, 프로덕션 빌드에서는 수행하지 않는 경우 전역 상수를 사용하여 로깅을 수행할지 여부를 결정할 수 있습니다. 이것이 DefinePlugin가 유용한 이유입니다. 이 플러그인을 설정하고 개발 및 프로덕션 빌드 환경을 잊어버리세요.
new webpack.DefinePlugin({
// Definitions...
});
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');
기능 플래그를 사용하여 프로덕션/개발 빌드 기능을 활성화/비활성화 할 수 있습니다.
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'),
});
runtimeValuefunction (getterFunction, [string] | true | object) => getterFunction()
파일에 의존하는 값으로 변수를 정의할 수 있으며 이러한 파일이 파일 시스템에서 변경 될 때 재평가 됩니다. 이는 감시된 파일이 변경될 때 webpack이 재빌드 됨을 의미합니다.
webpack.DefinePlugin.runtimeValue 함수에는 두 가지 인자가 있습니다.
첫 번째 인자는 정의에 할당할 값을 반환 해야 하는 function(module, key, version)입니다.
두 번째 인자는 감시할 파일 경로의 배열이거나 모듈을 캐시 할 수 없음으로 표시하는 true 플래그일 수 있습니다. 5.26.0 버전부터는 아래의 속성을 가진 객체 인자를 사용할 수 있습니다.
fileDependencies?: string[] 함수가 의존하는 파일 목록입니다.contextDependencies?: string[] 함수가 의존하는 디렉터리 목록입니다.missingDependencies?: string[] 함수가 의존하는 존재하지 않는 파일 목록입니다.buildDependencies?: string[] 함수가 의존하는 빌드 의존성 목록입니다.version?: string | () => string 함수의 버전입니다.const fileDep = path.resolve(__dirname, 'sample.txt');
new webpack.DefinePlugin({
BUILT_AT: webpack.DefinePlugin.runtimeValue(Date.now, {
fileDependencies: [fileDep],
}),
});
BUILT_AT의 값은 'sample.txt'가 파일 시스템에서 마지막으로 업데이트된 시간입니다. (예: 1597953013291)
DllPlugin과 DllReferencePlugin은 빌드 시간 성능을 크게 향상시키는 방식으로 번들을 분할하는 수단을 제공합니다. "DLL"이라는 용어는 원래 Microsoft에서 도입한 동적 링크 라이브러리를 나타냅니다.
이 플러그인은 dll 전용 번들을 생성하기 위해 단독으로 별도의 webpack 설정에서 사용됩니다. 의존성을 매핑하기 위해 DllReferencePlugin에서 사용하는 manifest.json파일을 생성합니다.
context (선택): 매니페스트 파일의 요청 컨텍스트 (기본값은 webpack 컨텍스트)format (boolean = false): true인 경우 매니페스트 json 파일(출력)이 형식화됩니다.name: 노출된 dll 함수의 이름 (TemplatePaths: [fullhash], [chunkhash], [contenthash], & [name] )path: 매니페스트 json 파일의 절대 경로 (출력)entryOnly (boolean = true): true인 경우 엔트리 포인트만 노출됩니다.type: dll 번들의 유형new webpack.DllPlugin(options);
주어진 경로에 기록되는 manifest.json을 생성합니다. 여기에는 require와 import 요청에서 모듈 id로의 매핑이 포함됩니다. 이는 DllReferencePlugin 에서 사용됩니다.
이 플러그인을 output.library옵션과 결합하여 dll 함수를 노출(전역 범위로 확대)합니다.
이 플러그인은 기본 webpack 설정에서 사용되며, 사전 빌드된 의존성을 require 하기 위해 dll 전용 번들을 참조합니다.
context: 매니페스트(또는 콘텐츠 프로퍼티)에 있는 요청의 (절대 경로) 컨텍스트extensions: dll 번들의 모듈을 해결하는데 사용되는 확장입니다(‘유효범위’를 사용할 때만 사용).manifest : content 및 name을 포함하는 객체 또는 컴파일 시 로드될 JSON 매니페스트의 절대 경로에 대한 문자열content (선택): 요청에서 모듈 id 로의 매핑(기본값은 manifest.content)name (선택): dll이 노출되는 식별자(기본값은 manifest.name)(externals 참조)scope (선택): dll의 콘텐츠에 접근하는데 사용되는 접두사sourceType (선택): dll이 노출되는 방법(libraryTarget)new webpack.DllReferencePlugin(options);
dll 매니페스트 파일을 참조하여 의존성 이름을 모듈 id에 매핑한 다음, 내부 __webpack_require__함수를 사용하여 필요에 따라 요청합니다.
이 플러그인은 scoped 와 mapped 두 가지 모드에서 사용할 수 있습니다.
dll의 콘텐츠는 모듈 접두사 아래에서 접근 가능합니다. 즉, scope = 'xyz'로 dll의 파일 abc 는 require('xyz/abc')를 통해 접근할 수 있습니다.
dll의 콘텐츠는 현재 디렉터리에 매핑됩니다. 필요한 파일이 dll의 파일과 확인 후 일치하는 경우, dll의 파일이 대신 사용됩니다.
이것은 dll 번들의 모든 파일을 해석한 후 발생하기 때문에 dll 번들의 사용자에 대해 동일한 경로를 사용할 수 있어야 합니다. 즉, dll에 lodash 가 포함되어 있고 abc 파일이 있으면 require('lodash') 및require('./abc') 가 메인 번들로 빌드되지 않고 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',
});
두 개의 개별 예제 폴더로, 유효범위와 컨텍스트를 보여줍니다.
EnvironmentPlugin을 사용해 process.env 키에 DefinePlugin을 간단히 적용할 수 있습니다.
EnvironmentPlugin은 키로 구성된 배열 혹은 키에 기본값이 매핑된 객체를 받습니다.
new webpack.EnvironmentPlugin(['NODE_ENV', 'DEBUG']);
이는 다음과 같은 DefinePlugin 적용과 동일합니다.
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.DEBUG': JSON.stringify(process.env.DEBUG),
});
또는, EnvironmentPlugin은 키에 기본값을 매핑한 객체를 지원합니다. 키가 process.env에 정의되지 않은 경우에는 기본값을 사용합니다.
new webpack.EnvironmentPlugin({
NODE_ENV: 'development', // process.env.NODE_ENV가 정의되지 않은 경우 'development'를 사용하세요.
DEBUG: false,
});
Example:
지금까지 구성해온 EnvironmentPlugin 설정을 테스트 파일 entry.js에 적용했을 때 어떻게 동작하는지 알아봅시다.
if (process.env.NODE_ENV === 'production') {
console.log('Welcome to production');
}
if (process.env.DEBUG) {
console.log('Debugging output');
}
빌드하기 위해 터미널에서 NODE_ENV=production webpack을 실행했을 때 entry.js는 다음과 같습니다.
if ('production' === 'production') {
// <-- NODE_ENV의 'production'이 사용됩니다.
console.log('Welcome to production');
}
if (false) {
// <-- 기본값이 사용됩니다.
console.log('Debugging output');
}
DEBUG=false webpack을 실행하면 다음과 같습니다.
if ('development' === 'production') {
// <-- 기본값이 사용됩니다.
console.log('Welcome to production');
}
if ('false') {
// <-- DEBUG의 'false'가 사용됩니다.
console.log('Debugging output');
}
다음과 같은 EnvironmentPlugin 설정은 저장소의 마지막 커밋에 따른 process.env.GIT_VERSION (예시 "v5.4.0-2-g25139f57f")과 process.env.GIT_AUTHOR_DATE (예시 "2020-11-04T12:25:16+01:00")를 제공합니다.
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'),
});
써드 파티 DotenvPlugin (dotenv-webpack)을 사용해 dotenv 변수를 사용할 수 있습니다.
// .env
DB_HOST=127.0.0.1
DB_PASS=foobar
S3_API=mysecretkey
new Dotenv({
path: './.env', // .env 파일 경로 (기본값)
safe: true, // .env.example 로드 (기본값은 dotenv-safe를 사용하지 않는 "false")
});
This version of eslint-webpack-plugin only supports webpack 5. For the webpack 4, see the 2.x branch.
This plugin uses ESlint to find and fix problems in your JavaScript code during the Webpack build process.
To begin, you'll need to install eslint-webpack-plugin:
npm install eslint-webpack-plugin --save-dev
or
yarn add -D eslint-webpack-plugin
or
pnpm add -D eslint-webpack-plugin
[!NOTE]
You also need to install
eslint >= 8from npm, if you haven't already:
npm install eslint --save-dev
or
yarn add -D eslint
or
pnpm add -D eslint
Then add the plugin to your webpack configuration. For example:
const ESLintPlugin = require("eslint-webpack-plugin");
module.exports = {
// ...
plugins: [new ESLintPlugin(options)],
// ...
};
You can pass ESLint Node.js API options.
[!NOTE]
The config option you provide will be passed to the
ESLintclass. This is a different set of options than what you'd specify inpackage.jsonoreslint.config.js(since ESLint v9.0.0, formerly.eslintrc). See the ESlint docs for more details.
[!WARNING]
In eslint-webpack-plugin version 1 the options were passed to the now-deprecated CLIEngine.
cachetype cache = boolean;
trueThe cache is enabled by default to decrease execution time.
cacheLocationtype cacheLocation = string;
node_modules/.cache/eslint-webpack-plugin/.eslintcacheSpecify the path to the cache location. Can be a file or a directory.
configTypetype configType = "flat" | "eslintrc";
flatSpecify the type of configuration to use with ESLint.
eslintrc is the classic configuration format available in most ESLint versions.flat is the new format introduced in ESLint 8.21.0.The new configuration format is explained in its own documentation.
contexttype context = string;
compiler.contextBase directory for linting.
eslintPathtype eslintPath = string;
eslintPath to eslint instance that will be used for linting.
If the eslintPath is a folder like a official ESlint, or specify a formatter option, now you don't have to install eslint.
extensionstype extensions = string | string[];
'js'Specify file extensions that should be checked.
excludetype exclude = string | string[];
'node_modules'Specify the files/directories to exclude. Must be relative to options.context.
resourceQueryExcludetype resourceQueryExclude = RegExp | RegExp[];
[]Specify the resource query to exclude.
filestype files = string | string[];
nullSpecify directories, files, or globs. Must be relative to options.context.
Directories are traversed recursively looking for files matching options.extensions.
File and glob patterns ignore options.extensions.
fixtype fix = boolean;
falseWill enable ESLint autofix feature.
Be careful: this option will modify source files.
formattertype formatter =
| string
| ((
results: import("eslint").ESLint.LintResult[],
data?: import("eslint").ESLint.LintResultData | undefined,
) => string);
'stylish'Accepts a function that receives an array of ESLint messages (object) as its argument and must return a string as output.
You can use official ESlint formatters.
lintDirtyModulesOnlytype lintDirtyModulesOnly = boolean;
falseLint only changed files, skipping initial lint on build start.
threadstype threads = boolean | number;
falseWill run lint tasks across a thread pool. The pool size is automatic unless you specify a number.
By default the plugin will auto adjust error reporting depending on eslint errors/warnings counts.
You can still force this behavior by using emitError or emitWarning options:
emitErrortype emitError = boolean;
trueThe errors found will always be emitted, to disable set to false.
emitWarningtype emitWarning = boolean;
trueThe warnings found will always be emitted, to disable set to false.
failOnErrortype failOnError = boolean;
trueWill cause the module build to fail if any errors are found, to disable set to false.
failOnWarningtype failOnWarning = boolean;
falseWill cause the module build to fail if any warnings are found, if set to true.
quiettype quiet = boolean;
falseWill process and report errors only and ignore warnings, if set to true.
outputReporttype outputReport =
| boolean
| {
filePath?: string | undefined;
formatter?:
| (
| string
| ((
results: import("eslint").ESLint.LintResult[],
data?: import("eslint").ESLint.LintResultData | undefined,
) => string)
)
| undefined;
};
falseWrite ESLint results to a file, for example a checkstyle xml file for use for reporting on Jenkins CI.
formatter for the output file.
if none is passed in the default/configured formatter will be used.We welcome all contributions!
If you're new here, please take a moment to review our contributing guidelines.
EvalSourceMapDevToolPlugin을 사용하면 소스맵 생성을 보다 세밀하게 제어할 수 있습니다. 또한 devtool 설정 옵션의 특정한 세팅에 의해 자동으로 활성화됩니다.
new webpack.EvalSourceMapDevToolPlugin(options);
다음과 같은 옵션이 지원됩니다.
test (string|RegExp|array): 모듈의 확장자를 기반으로 하는 소스맵을 포함합니다(기본값은 .js 및 .css).
include (string|RegExp|array): 주어진 값과 일치하는 모듈 경로에 대한 소스맵을 포함합니다.
exclude (string|RegExp|array): 소스맵 생성에서 주어진 값과 일치하는 모듈을 제외합니다.
append (string|function): 원래 애셋에 주어진 값을 추가합니다. 보통 #sourceMappingURL 을 주석으로 합니다. [url]은 소스맵 파일의 URL로 대체됩니다.
버전 5.84.0부터 webpack은 경로와 애셋 정보 객체를 인수로 받아들이고 문자열을 반환하는 'append' 옵션을 허용합니다.
(pathData: PathData, assetInfo?: AssetInfo) => string;
moduleFilenameTemplate (string): output.devtoolModuleFilenameTemplate을 참조하세요.
module (boolean): 로더가 소스맵을 생성해야 하는지 여부를 나타냅니다(기본값은 true).
columns (boolean): 열 매핑을 사용해야 하는지 여부를 나타냅니다(기본값은 true).
protocol (string): 사용자가 기본 프로토콜(webpack-internal://)을 오버라이드 할 수 있습니다.
다음 예시는 EvalSourceMapDevToolPlugin이 흔히 사용되는 사례를 보여줍니다.
다음 코드를 사용하여 설정 옵션 devtool: eval-source-map을 동등한 커스텀 플러그인 설정으로 바꿀 수 있습니다.
module.exports = {
// ...
devtool: false,
plugins: [new webpack.EvalSourceMapDevToolPlugin({})],
};
다음 코드는 vendor.js 번들에 있는 모든 모듈에 대한 소스맵을 제외합니다.
new webpack.EvalSourceMapDevToolPlugin({
exclude: ['vendor.js'],
});
이 플러그인은 해시가 모듈의 상대 경로를 기반으로 해 모듈 ID로 4개의 문자열이 생성됩니다. 프로덕션에 사용할 것을 권장합니다.
new webpack.ids.HashedModuleIdsPlugin({
// 옵션...
});
이 플러그인은 다음 옵션을 지원합니다:
context: 이름을 만들기 위한 컨텍스트 디렉터리 (절대 경로).hashFunction: 사용할 해싱 알고리즘, 기본 값은 'md4'입니다. Node.JS의 crypto.createHash의 모든 기능이 지원됩니다.hashDigest: 해시를 생성할 때 사용할 인코딩, 기본 값은 'base64'입니다. Node.JS의 hash.digest의 모든 인코딩이 지원됩니다.hashDigestLength: 사용할 해시 다이제스트의 접두사 길이, 기본 값은 4입니다. 생성된 일부 ID는 모듈 ID 충돌을 피하기 위해 여기에서 지정된 것보다 길 수 있습니다.다음은 이 플러그인을 사용하는 방법의 예시입니다:
new webpack.ids.HashedModuleIdsPlugin({
context: __dirname,
hashFunction: 'sha256',
hashDigest: 'hex',
hashDigestLength: 20,
});
HMR로 알려져 있는 Hot Module Replacement을 활성화합니다.
HMR을 활성화하는 것은 간단하며 대부분의 경우 옵션이 필요하지 않습니다.
new webpack.HotModuleReplacementPlugin({
// Options...
});
This plugin can use 3 tools to optimize and minify your HTML:
swc - very fast Rust-based platform for the Web.html-minifier-terser (by default) - JavaScript-based HTML minifier.@minify-html/node - A Rust HTML minifier meticulously optimised for speed and effectiveness, with bindings for other languages.This plugin integrates seamlessly into your Webpack build pipeline to reduce HTML size and improve loading performance.
To begin, you'll need to install html-minimizer-webpack-plugin:
npm install html-minimizer-webpack-plugin --save-dev
or
yarn add -D html-minimizer-webpack-plugin
or
pnpm add -D html-minimizer-webpack-plugin
Additional step: If you want to use @swc/html you need to install it:
npm install @swc/html --save-dev
or
yarn add -D @swc/html
or
pnpm add -D @swc/html
Additional step: If you want to use @minify-html/node you need to install it:
npm install @minify-html/node --save-dev
or
yarn add -D @minify-html/node
or
pnpm add -D @minify-html/node
Then add the plugin to your webpack configuration. For example:
webpack.config.js
const CopyPlugin = require("copy-webpack-plugin");
const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
{
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
// `...`
// For `html-minifier-terser`:
//
new HtmlMinimizerPlugin(),
// For `@swc/html`:
//
// HTML documents - HTML documents with `Doctype` and `<html>/`<head>`/`<body>` tags
//
// Options - https://github.com/swc-project/bindings/blob/main/packages/html/index.ts#L5
//
// new HtmlMinimizerPlugin({
// minify: HtmlMinimizerPlugin.swcMinify,
// minimizerOptions: {}
// })
//
//
// HTML fragments - HTML fragments, i.e. HTML files without doctype or used in `<template></template>` tags or HTML parts which injects into another HTML parts
//
// Options - https://github.com/swc-project/bindings/blob/main/packages/html/index.ts#L38
//
// new HtmlMinimizerPlugin({
// minify: HtmlMinimizerPlugin.swcMinifyFragment,
// minimizerOptions: {}
// })
],
},
};
[!NOTE]
HTML will only be minimized in production mode by default. To enable minification in development, explicitly set
optimization.minimize: true.
Finally, run webpack using the method you normally use (e.g., via CLI or an npm script).
[!NOTE]
Removing and collapsing spaces in the tools differ (by default).
@swc/html- Remove and collapse whitespaces only in safe places (for example - aroundhtmlandbodyelements, inside theheadelement and between metadata elements -<meta>/script/link/etc.)html-minifier-terser- Always collapse multiple whitespaces to 1 space (never remove it entirely), but you can change it usingoptions@minify-html/node- Please read documentation https://github.com/wilsonzlin/minify-html#whitespace for detailed whitespace behavior.
testType:
type test = string | RegExp | (string | RegExp)[];
Default: /\.html(\?.*)?$/i
Test to match files against.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
test: /\.foo\.html/i,
}),
],
},
};
includeType:
type include = string | RegExp | (string | RegExp)[];
Default: undefined
Files to include for minification.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
include: /\/includes/,
}),
],
},
};
excludeType:
type exclude = string | RegExp | (string | RegExp)[];
Default: undefined
Files to exclude from minification.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
exclude: /\/excludes/,
}),
],
},
};
parallelType:
type parallel = undefined | boolean | number;
Default: true
Enables multi-process parallelization to improve build performance.
If true, uses os.cpus().length - 1 or os.availableParallelism() - 1 (if available).
If number, sets the number of concurrent workers.
[!NOTE]
Parallelization can speed up your build significantly and is therefore highly recommended.
booleanEnable or disable multi-process parallel running.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
parallel: true,
}),
],
},
};
numberEnable multi-process parallel running and set number of concurrent runs.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
parallel: 4,
}),
],
},
};
minifyType:
type minify =
| ((
data: Record<string, string>,
minimizerOptions: Record<string, any>,
) => {
code: string;
errors?: unknown[] | undefined;
warnings?: unknown[] | undefined;
})
| ((
data: Record<string, string>,
minimizerOptions: Record<string, any>,
) => {
code: string;
errors?: unknown[] | undefined;
warnings?: unknown[] | undefined;
})[];
Default: HtmlMinimizerPlugin.htmlMinifierTerser
Allows you to override default minify function. By default, plugin uses html-minifier-terser package.
We currently support:
HtmlMinimizerPlugin.swcMinify (used to compress HTML documents, i.e. with HTML doctype and <html>/<body>/<head> tags)HtmlMinimizerPlugin.swcMinifyFragment (used to compress HTML fragments, i.e. when you have part of HTML which will be inserted into another HTML parts)HtmlMinimizerPlugin.htmlMinifierTerserHtmlMinimizerPlugin.minifyHtmlNode[!NOTE]
The difference between
swcMinifyandswcMinifyFragmentis the error reporting. You will get errors (invalid or broken syntax) if you have them in your HTML document or fragment. Which allows you to see all the errors and problems at the build stage.
Useful for using and testing unpublished versions or forks.
[!WARNING]
Always use
requireinsideminifyfunction whenparalleloption enabled.
functionYou can define a custom minify function, giving full control over how the HTML is processed.
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: [],
};
},
}),
],
},
};
arrayIf an array of functions is passed to the minify option, the minimizerOptions can be either as:
An array; If minimizerOptions is array, the function index in the minify array corresponds to the options object with the same index in the minimizerOptions array.
A single object; 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: [],
};
},
],
}),
],
},
};
minimizerOptionsType:
type minimizerOptions = Record<string, any> | Record<string, any>[];
Default:
{
caseSensitive: true,
collapseWhitespace: true,
conservativeCollapse: true,
keepClosingSlash: true,
minifyCSS: true,
minifyJS: true,
removeComments: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
}
Html-minifier-terser optimizations options.
objectApplies the same options to the default or custom minify function.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
minimizerOptions: {
collapseWhitespace: false,
},
}),
],
},
};
arrayThe 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: [],
};
},
],
}),
],
},
};
swc/htmlAvailable options.
HTML Documents:
const CopyPlugin = require("copy-webpack-plugin");
const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
type: "asset/resource",
},
],
},
plugins: [
new CopyPlugin({
patterns: [
{
context: path.resolve(__dirname, "dist"),
from: "./src/*.html",
},
],
}),
],
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
minify: HtmlMinimizerPlugin.swcMinify,
minimizerOptions: {
// Options - https://github.com/swc-project/bindings/blob/main/packages/html/index.ts#L5
},
}),
],
},
};
HTML Fragments:
Use this for partial HTML files (e.g. inside <template></template> tags or HTML strings).
const path = require("node:path");
const CopyPlugin = require("copy-webpack-plugin");
const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
type: "asset/resource",
},
],
},
plugins: [
new CopyPlugin({
patterns: [
{
context: path.resolve(__dirname, "dist"),
from: "./src/*.html",
},
],
}),
],
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
test: /\.template\.html$/i,
minify: HtmlMinimizerPlugin.swcMinifyFragment,
minimizerOptions: {
// Options - https://github.com/swc-project/bindings/blob/main/packages/html/index.ts#L38
},
}),
],
},
};
@minify-html/nodeAvailable options.
HTML Documents:
const CopyPlugin = require("copy-webpack-plugin");
const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
type: "asset/resource",
},
],
},
plugins: [
new CopyPlugin({
patterns: [
{
context: path.resolve(__dirname, "dist"),
from: "./src/*.html",
},
],
}),
],
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
minify: HtmlMinimizerPlugin.minifyHtmlNode,
minimizerOptions: {
// Options - https://github.com/wilsonzlin/minify-html#minification
},
}),
],
},
};
You can use multiple HtmlMinimizerPlugin plugins to compress different files with the different minify function.
We welcome all contributions! If you're new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.
HtmlWebpackPlugin은 webpack 번들을 제공하는 HTML 파일 생성을 단순화합니다. 이 플러그인은 매번 컴파일에 변경되는 해시로 된 파일 이름을 가진 webpack 번들에 특히 유용합니다. 플러그인이 HTML 파일을 생성하도록 하거나 lodash 템플릿을 사용하여 나만의 템플릿을 제공하거나 나만의 로더를 사용할 수 있습니다.
npm install --save-dev html-webpack-plugin
플러그인은 script 태그를 사용하여 body에 모든 webpack 번들을 포함하는 HTML5 파일을 생성합니다.
적용은 아래와 같이 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> 태그로 포함됩니다.
모든 설정 옵션은 plugin 문서를 참고하세요.
플러그인은 추가 기능을 지원합니다. 목록은 해당 문서를 참고하세요.
IgnorePlugin은 정규 표현식 또는 필터 함수와 일치하는 import 또는 require 호출에 대한 모듈 생성을 방지합니다.
resourceRegExp: 리소스 테스트를 위한 정규 표현식contextRegExp: (선택) 컨텍스트 (디렉터리) 테스트를 위한 정규 표현식new webpack.IgnorePlugin({ resourceRegExp, contextRegExp });
checkResource (resource, context)는 resource와 context를 인수로 받는 필터 함수로, 불리언 값을 반환해야 합니다.new webpack.IgnorePlugin({
checkResource(resource) {
// 리소스를 사용합니다
return true | false;
},
});
moment 2.18 부터, 모든 로케일이 코어 라이브러리와 함께 번들로 제공됩니다 (깃허브 이슈를 참고하세요).
IgnorePlugin에 전달된 resourceRegExp 파라미터는 import 또는 require 되는 해석된 파일 이름 혹은 절대 모듈 이름에 대해 테스트 되지 않고, 가져오기가 실행되는 소스 코드 내에서 require 또는 import로 전달된 문자열 에 대해 테스트 됩니다. 예를 들어 node_modules/moment/locale/*.js를 제외하려는 경우 다음과 같은 작업이 수행되지 않습니다.
-new webpack.IgnorePlugin({ resourceRegExp: /moment\/locale\// });
moment는 아래의 코드로 가져오기 때문입니다.
require('./locale/' + name);
첫 번째 정규 표현식은 './locale/' 문자열과 일치해야 합니다. 그다음 두 번째 contextRegExp 파라미터를 사용하여 가져오기가 수행된 특정 디렉터리를 선택합니다. 다음은 로케일 파일이 무시되는 경우입니다.
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
});
이는 'moment'로 끝나는 디렉터리에서 './locale'과 일치하는 모든 require 문이 무시됨을 의미합니다.
A 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 four different tools to optimize or generate 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.sharp - High performance Node.js image processing, the fastest module to resize and compress JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.svgo - tool for optimizing SVG vector graphics files. Supports only SVG files minification.[!WARNING]
By default, we don’t install any additional packages.
To begin, you'll need to install image-minimizer-webpack-plugin along with an image optimizer or generator:
npm install image-minimizer-webpack-plugin imagemin --save-dev
[!WARNING]
imagemin uses plugins to optimize or generate images, so you’ll need to install those as well.
squoosh:npm install image-minimizer-webpack-plugin @squoosh/lib --save-dev
npm install image-minimizer-webpack-plugin sharp --save-dev
svgo:npm install image-minimizer-webpack-plugin svgo --save-dev
Images can be optimized in two modes:
imagemin[!NOTE]
- imagemin-mozjpeg can be configured in lossless and lossy mode.
- imagemin-svgo can be configured in lossless and lossy mode.
Explore the available options to find the best results for your use case.
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+, you need to use the official SVGO configuration
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: "asset",
},
],
},
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
// Lossless optimization with custom option
// Feel free to experiment with options for better results
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
// SVGO configuration here https://github.com/svg/svgo#configuration
[
"svgo",
{
plugins: [
{
name: "preset-default",
params: {
overrides: {
removeViewBox: false,
addAttributesToSVGElement: {
params: {
attributes: [
{ xmlns: "http://www.w3.org/2000/svg" },
],
},
},
},
},
},
],
},
],
],
},
},
}),
],
},
};
squooshnpm install @squoosh/lib --save-dev
Recommended @squoosh/lib options for lossy optimization
For lossy optimization, we recommend using the default settings of @squoosh/lib package.
The default values and supported file types for each option can be found in the codecs.ts file under codecs directory.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
// You need this, if you are using `import file from "file.ext"`; not needed for `new URL(...)` syntax
{
test: /\.(jpe?g|png)$/i,
type: "asset",
},
],
},
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.squooshMinify,
options: {
// Your options for `squoosh` here
},
},
}),
],
},
};
Recommended squoosh options for lossless optimization
For lossless optimization we recommend using the options listed below in minimizer.options.encodeOptions.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
// You need this, if you are using `import file from "file.ext"`, for `new URL(...)` syntax you don't need it
{
test: /\.(jpe?g|png)$/i,
type: "asset",
},
],
},
optimization: {
minimizer: [
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.squooshMinify,
options: {
encodeOptions: {
mozjpeg: {
// That setting might be close to lossless, but it’s not guaranteed
// See https://github.com/GoogleChromeLabs/squoosh/issues/85
quality: 100,
},
webp: {
lossless: 1,
},
avif: {
// See https://github.com/GoogleChromeLabs/squoosh/blob/dev/codecs/avif/enc/README.md
cqLevel: 0,
},
},
},
},
}),
],
},
};
sharpnpm install sharp --save-dev
Recommended sharp options for lossy optimization
For lossy optimization we recommend using the default settings of sharp package.
The default values and supported file types for each option can be found in the sharp documentation.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
// You need this, if you are using `import file from "file.ext"`, for `new URL(...)` syntax you don't need it
{
test: /\.(jpe?g|png)$/i,
type: "asset",
},
],
},
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify,
options: {
encodeOptions: {
// Customize your `sharp` options here
// See https://sharp.pixelplumbing.com/api-output
},
},
},
}),
],
},
};
Recommended sharp options for lossless optimization
For lossless optimization we recommend using the options listed below in minimizer.options.encodeOptions.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
// You need this, if you are using `import file from "file.ext"`. Not needed for `new URL(...)` syntax
{
test: /\.(jpe?g|png)$/i,
type: "asset",
},
],
},
optimization: {
minimizer: [
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify,
options: {
encodeOptions: {
jpeg: {
// https://sharp.pixelplumbing.com/api-output#jpeg
quality: 100,
},
webp: {
// https://sharp.pixelplumbing.com/api-output#webp
lossless: true,
},
avif: {
// https://sharp.pixelplumbing.com/api-output#avif
lossless: true,
},
// PNG by default sets the quality to 100%, which is same as lossless
// https://sharp.pixelplumbing.com/api-output#png
png: {},
// GIF does not support lossless compression at all
// https://sharp.pixelplumbing.com/api-output#gif
gif: {},
},
},
},
}),
],
},
};
svgonpm install svgo --save-dev
Recommended svgo options for optimization
For SVG optimization we recommend using the options listed below in minimizer.options.encodeOptions.
The default values for plugins can be found in the svgo plugins source code.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
// You need this, if you are using `import file from "file.ext"`. Not needed for `new URL(...)` syntax
{
test: /\.(svg)$/i,
type: "asset",
},
],
},
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.svgoMinify,
options: {
encodeOptions: {
// Pass over SVGs multiple times to ensure all optimizations are applied (False by default)
multipass: true,
plugins: [
// Built-in plugin preset enabled by default
// See: https://github.com/svg/svgo#default-preset
"preset-default",
],
},
},
},
}),
],
},
};
If you want to use loader or plugin standalone see sections below, but this is not recommended.
By default, plugin configures loader (please use the loader option if you want to disable this behaviour), therefore you should not setup standalone loader when you use a plugin setup.
Loader optimizes or generates images using options, so inlined images via data URI (i.e. data:) will be optimized or generated too, non-inlined images will be optimized too.
squoosh and sharp currently)The plugin supports the following query parameters:
width/w - allows you to set the image width
height/h - allows you to set the image height
as - to specify the preset option
Only supported for sharp currently:
unit/u - can be px or percent and allows you to resize by a percentage of the image's size.
Examples:
const myImage1 = new URL("image.png?width=150&height=120", import.meta.url);
const myImage2 = new URL("image.png?w=150&h=120", import.meta.url);
// You can omit one of the parameters to auto-scale
const myImage3 = new URL("image.png?w=150", import.meta.url);
// It works with the `preset` query parameter
const myImage4 = new URL("image.png?as=webp&w=150&h=120", import.meta.url);
// You can use `auto` to reset `width` or `height` from the `preset` option
const myImage5 = new URL("image.png?as=webp&w=150&h=auto", import.meta.url);
// You can use `unit` to get the non-retina resize of images that are retina sized
const myImage6 = new URL("image.png?width=50&unit=percent", import.meta.url);
.class {
background: url("./image.png?width=150&height=120");
}
<picture>
<source srcset="photo.jpg?as=avif&width=150&height=120" type="image/avif" />
<source srcset="photo.jpg?as=webp&width=150&height=120" type="image/webp" />
<img src="photo.jpg?width=150&height=120" alt="photo" />
</picture>
[!NOTE]
You need to setup
avifandwebppresets, See the example for webp.
In your webpack.config.js, add the ImageMinimizerPlugin.loader and specify the asset modules options (if you use images in import):
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
// You need this, if you are using `import file from "file.ext"`. Not needed for `new URL(...)` syntax
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: "asset",
},
// We recommend using only for the "production" mode
{
test: /\.(jpe?g|png|gif|svg)$/i,
enforce: "pre",
use: [
{
loader: ImageMinimizerPlugin.loader,
options: {
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
},
},
],
},
],
},
};
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
module: {
rules: [
// You need this, if you are using `import file from "file.ext"`. Not needed for `new URL(...)` syntax
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: "asset",
},
],
},
optimization: {
minimizer: [
// Extend default minimizer, i.e. `terser-webpack-plugin` for JS
"...",
// We recommend using only for the "production" mode
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
loader: false, // Disable the `loader`
}),
],
},
};
testType:
type test = string | RegExp | (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 = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
test: /\.(jpe?g|png|gif|svg)$/i,
}),
],
},
};
includeType:
type include = string | RegExp | (string | RegExp)[];
Default: undefined
Files to include.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
include: /\/includes/,
}),
],
},
};
excludeType:
type exclude = string | RegExp | (string | RegExp)[];
Default: undefined
Files to exclude.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
exclude: /\/excludes/,
}),
],
},
};
minimizerType:
type minimizer =
| {
implementation: (
original: {
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
},
options?: Record<string, any> | undefined,
) => Promise<{
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
}> & {
setup?: (() => void) | undefined;
teardown?: (() => void) | undefined;
};
options?: Record<string, any> | undefined;
filter?: (source: Buffer, sourcePath: string) => boolean | undefined;
filename?:
| string
| ((
pathData: {
filename?: string | undefined;
},
assetInfo?: import("webpack").AssetInfo | undefined,
) => string)
| undefined;
}
| {
implementation: (
original: {
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
},
options?: Record<string, any> | undefined,
) => Promise<{
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
}> & {
setup?: (() => void) | undefined;
teardown?: (() => void) | undefined;
};
options?: Record<string, any> | undefined;
filter?: (source: Buffer, sourcePath: string) => boolean | undefined;
filename?:
| string
| ((
pathData: {
filename?: string | undefined;
},
assetInfo?: import("webpack").AssetInfo | undefined,
) => string)
| undefined;
}[];
Default: undefined
Allows to setup default minify function.
ImageMinimizerPlugin.imageminMinifyImageMinimizerPlugin.squooshMinifyImageMinimizerPlugin.sharpMinifyImageMinimizerPlugin.svgoMinifyimageminwebpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
// Implementation
implementation: ImageMinimizerPlugin.imageminMinify,
// Options
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
}),
],
},
};
More information and examples here.
squooshwebpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
// Implementation
implementation: ImageMinimizerPlugin.squooshMinify,
// Options
options: {
encodeOptions: {
mozjpeg: {
quality: 90,
},
},
},
},
}),
],
},
};
More information and examples here.
sharpwebpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
// Implementation
implementation: ImageMinimizerPlugin.sharpMinify,
// Options
options: {
encodeOptions: {
jpeg: {
quality: 90,
},
},
},
},
}),
],
},
};
More information and examples here.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: async (original, options) => {
const inputExt = path.extname(original.filename).toLowerCase();
if (inputExt !== ".xxx") {
// Return `null` if the implementation does not support this file type
return null;
}
let result;
try {
result = await minifyAndReturnBuffer(original.data);
} catch (error) {
// Store error and return `null` if there was an error
original.errors.push(error);
return null;
}
return {
filename: original.filename,
data: result,
warnings: [...original.warnings],
errors: [...original.errors],
info: {
...original.info,
// Please always set it to prevent double minification
minimized: true,
// Optional
minimizedBy: ["custom-name-of-minimication"],
},
};
},
options: {
// Custom options
},
},
}),
],
},
};
Allows to setup multiple minimizers.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: [
{
// `sharp` will handle all bitmap formats (JPG, PNG, GIF, ...)
implementation: ImageMinimizerPlugin.sharpMinify,
// exclude SVG if implementation support it. Not required for `sharp`.
// filter: (source, sourcePath) => !(/\.(svg)$/i.test(sourcePath)),
options: {
encodeOptions: {
// Your options for `sharp`
// https://sharp.pixelplumbing.com/api-output
},
},
},
{
// `svgo` will handle vector images (SVG)
implementation: ImageMinimizerPlugin.svgoMinify,
options: {
encodeOptions: {
// Pass over SVGs multiple times to ensure all optimizations are applied. False by default
multipass: true,
plugins: [
// set of built-in plugins enabled by default
// see: https://github.com/svg/svgo#default-preset
"preset-default",
],
},
},
},
],
}),
],
},
};
implementationType:
type implementation = (
original: {
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
},
options?: BasicTransformerOptions<T>,
) => Promise<{
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
}> & {
setup?: (() => void) | undefined;
teardown?: (() => void) | undefined;
};
Default: undefined
Configure the default implementation.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
// Implementation
implementation: ImageMinimizerPlugin.sharpMinify,
// Options
options: {
encodeOptions: {
jpeg: {
quality: 90,
},
},
},
},
}),
],
},
};
optionsType:
type options = Record<string, any>;
Default: undefined
Options for the implementation option (i.e. options for imagemin/squoosh/sharp/custom implementation).
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify,
// Options
options: {
encodeOptions: {
jpeg: {
quality: 90,
},
},
},
},
}),
],
},
};
filterType:
type filter = (source: Buffer, sourcePath: string) => boolean | undefined;
Default: () => true
Allows filtering of images for optimization or generation.
Return true to process (optimize or generate) the image, or false to skip it.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
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;
},
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
}),
],
},
};
filenameType:
type filename =
| string
| ((
pathData: {
filename?: string | undefined;
},
assetInfo?: import("webpack").AssetInfo | undefined,
) => string)
| undefined;
Default: undefined
Allows to set the filename.
Supported values see in webpack template strings (see the File-level section for supported patterns).
We also support [width] and [height] placeholders (only when using sharp and squoosh).
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
filename: "optimized-[name][ext]",
implementation: ImageMinimizerPlugin.sharpMinify,
// Options
options: {
encodeOptions: {
jpeg: {
quality: 90,
},
},
},
},
}),
],
},
};
Example function usage:
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
filename: () => "optimized-[name][ext]",
implementation: ImageMinimizerPlugin.sharpMinify,
// Options
options: {
encodeOptions: {
jpeg: {
quality: 90,
},
},
},
},
}),
],
},
};
generatorType:
type generator = {
implementation: (
original: {
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
},
options?: Record<string, any> | undefined,
) => Promise<{
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
}> & {
setup?: (() => void) | undefined;
teardown?: (() => void) | undefined;
};
options?: Record<string, any> | undefined;
filter?: (source: Buffer, sourcePath: string) => boolean | undefined;
filename?:
| string
| ((
pathData: {
filename?: string | undefined;
},
assetInfo?: import("webpack").AssetInfo | undefined,
) => string)
| undefined;
preset?: string | undefined;
type?: "import" | "asset" | undefined;
}[];
Default: undefined
Allow to setup default image generators.
This is useful when you want to generate additional formats like webp, avif, etc., from the original images.
[!WARNING]
If no generator was found for the image (i.e. no
?as=webpwas found in query params), theminimizeroption will be used. Therefore, it is recommended to configure generator outputs optimized image.
[!WARNING]
The option will not work if you disable the
loader(i.e. set theloaderoption tofalse).
ImageMinimizerPlugin.imageminGenerateImageMinimizerPlugin.squooshGenerateImageMinimizerPlugin.sharpGenerateimageminExample webp generator:
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
// You can apply generator using `?as=webp`
// You can use any name and provide more options
preset: "webp",
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
// Please specify only one plugin here, multiple plugins will not work
plugins: ["imagemin-webp"],
},
},
],
}),
],
},
};
squooshwebpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
// You can apply generator using `?as=webp`, you can use any name and provide more options
preset: "webp",
implementation: ImageMinimizerPlugin.squooshGenerate,
options: {
encodeOptions: {
// Please specify only one codec here, multiple codecs will not work
webp: {
quality: 90,
},
},
},
},
],
}),
],
},
};
sharpwebpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
// You can apply generator using `?as=webp`, you can use any name and provide more options
preset: "webp",
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
encodeOptions: {
// Please specify only one codec here, multiple codecs will not work
webp: {
quality: 90,
},
},
},
},
],
}),
],
},
};
Now you can generate the new image using:
// Old approach for getting URL
import webp from "./file.jpg?as=webp";
// Assets modules
console.log(new URL("./file.jpg?as=webp"));
div {
background: url("./file.jpg?as=webp");
}
You can use ?as=webp in any type of files.
Example multiple generators:
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
// You can apply generator using `?as=webp`, you can use any name and provide more options
preset: "webp",
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
encodeOptions: {
webp: {
lossless: false,
},
},
},
},
{
// You can apply generator using `?as=avif`, you can use any name and provide more options
preset: "avif",
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
encodeOptions: {
avif: {
lossless: false,
},
},
},
},
],
}),
],
},
};
squoosh and sharp generator supports more options, for example you can resize an image:
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
// You can apply generator using `?as=webp-100-50`, you can use any name and provide more options
preset: "webp-100-50",
// implementation: ImageMinimizerPlugin.squooshGenerate,
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
resize: {
enabled: true,
width: 100,
height: 50,
},
encodeOptions: {
webp: {
quality: 90,
},
},
},
},
],
}),
],
},
};
You can find more information in the squoosh GitHub repository.
For only sharp currently, you can even generate the non-retina resizes of images:
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
// You can apply generator using `?as=webp-1x`, you can use any name and provide more options
preset: "webp-1x",
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
resize: {
enabled: true,
width: 50,
unit: "percent",
},
encodeOptions: {
webp: {
quality: 90,
},
},
},
},
],
}),
],
},
};
You can use your own generator implementation.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
// You can apply generator using `?as=webp`, you can use any name and provide more options
preset: "webp",
implementation: async (original, options) => {
const inputExt = path.extname(original.filename).toLowerCase();
if (inputExt !== ".xxx") {
// Store error and return `null` if the implementation does not support this file type
original.errors.push(error);
return null;
}
let result;
try {
result = await minifyAndReturnBuffer(original.data);
} catch (error) {
// Store error and return `null` if there was an error
original.errors.push(error);
return null;
}
return {
filename: original.filename,
data: result,
warnings: [...original.warnings],
errors: [...original.errors],
info: {
...original.info,
// Please always set it to prevent double minification
generated: true,
// Optional
generatedBy: ["custom-name-of-minification"],
},
};
},
options: {
// Your options
},
},
],
}),
],
},
};
typeType:
type type = "import" | "asset" | undefined;
Default: "import"
Allows you to apply the generator for either import or assets from compilation (useful for copied assets).
By default, generators are applying on import/require, but sometimes you need to generate new images from other plugins (for example - copy-webpack-plugin).
If you need this, please set asset value for the type option.
webpack.config.js
const CopyPlugin = require("copy-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
generator: [
{
// Apply generator for copied assets
type: "asset",
// You can use `ImageMinimizerPlugin.squooshGenerate`
// You can use `ImageMinimizerPlugin.sharpGenerate`
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
plugins: ["imagemin-webp"],
},
},
],
}),
],
},
plugins: [new CopyPlugin({ patterns: ["images/**/*.png"] })],
};
presetType:
type preset = string | undefined;
Default: undefined
Configures the name of preset, i.e. you can use it in ?as=name.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
preset: "name",
// Implementation
implementation: ImageMinimizerPlugin.sharpMinify,
options: {
encodeOptions: {
jpeg: {
quality: 85,
},
},
},
},
],
}),
],
},
};
implementationType:
type implementation = (
original: {
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
},
options?: Record<string, any> | undefined,
) => Promise<{
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
}> & {
setup?: (() => void) | undefined;
teardown?: (() => void) | undefined;
};
Default: undefined
Configures the default implementation.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
preset: "name",
// Implementation
implementation: ImageMinimizerPlugin.sharpMinify,
options: {
encodeOptions: {
jpeg: {
quality: 85,
},
},
},
},
],
}),
],
},
};
optionsType:
type options = Record<string, any>;
Default: undefined
Options for the implementation (i.e. options for imagemin/squoosh/sharp/custom implementation).
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
preset: "name",
implementation: ImageMinimizerPlugin.sharpMinify,
// Options
options: {
encodeOptions: {
jpeg: {
quality: 90,
},
},
},
},
],
}),
],
},
};
filterType:
type filter = (source: Buffer, sourcePath: string) => boolean;
Default: () => true
Allows filtering of images for optimization/generation.
Return true to optimize the image, or false to skip it.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
preset: "name",
filter: (source, sourcePath) => {
// The `source` argument is a `Buffer` of the source file
// The `sourcePath` argument is an absolute path to the source
if (source.byteLength < 8192) {
return false;
}
return true;
},
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
],
}),
],
},
};
filenameType:
type filename =
| string
| ((
pathData: PathData,
assetInfo?: import("webpack").AssetInfo | undefined,
) => string);
Default: undefined
Allows to set the filename.
Supported values see in webpack template strings, under the File-level section.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
preset: "name",
filename: "generated-[name][ext]",
implementation: ImageMinimizerPlugin.sharpMinify,
// Options
options: {
encodeOptions: {
jpeg: {
quality: 90,
},
},
},
},
],
}),
],
},
};
Example of function usage:
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
generator: [
{
preset: "name",
filename: () => "generated-[name][ext]",
implementation: ImageMinimizerPlugin.sharpMinify,
// Options
options: {
encodeOptions: {
jpeg: {
quality: 90,
},
},
},
},
],
}),
],
},
};
severityErrorType:
type severityError = string;
Default: 'error'
Allows to choose how errors are displayed during image optimization.
Сan have the following values:
'off' - Suppresses both errors and warnings'warning' - Emits warnings instead of errors'error' - Emits errorswebpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
severityError: "warning",
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
}),
],
},
};
loaderType:
type loader = boolean;
Default: true
Automatically adding built-in loader, used to optimize/generate images.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
loader: false,
// `generator` will not work in this case
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
}),
],
},
};
concurrencyType:
type concurrency = number;
Default: Math.max(1, os.availableParallelism() - 1)
Maximum number of concurrency optimization processes in one time.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
concurrency: 3,
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
}),
],
},
};
deleteOriginalAssetsType:
type deleteOriginalAssets = boolean;
Default: true
Allows removing original assets after optimization.
Please use this option if you are set the filename option for the minimizer option, disable loader: false and want to keep optimized and not optimized assets.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
// Disable loader
loader: false,
// Allows to keep original asset and minimized assets with different filenames
deleteOriginalAssets: false,
minimizer: {
filename: "[path][name].webp",
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
}),
],
},
};
minimizerType:
type minimizer =
| {
implementation: (
original: {
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
},
options?: Record<string, any> | undefined,
) => Promise<{
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
}> & {
setup?: (() => void) | undefined;
teardown?: (() => void) | undefined;
};
options?: Record<string, any> | undefined;
filter?: (source: Buffer, sourcePath: string) => boolean | undefined;
filename?:
| string
| ((
pathData: {
filename?: string | undefined;
},
assetInfo?: import("webpack").AssetInfo | undefined,
) => string)
| undefined;
}
| {
implementation: (
original: {
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
},
options?: Record<string, any> | undefined,
) => Promise<{
filename: string;
data: Buffer;
warnings: Error[];
errors: Error[];
info: import("webpack").AssetInfo;
}> & {
setup?: (() => void) | undefined;
teardown?: (() => void) | undefined;
};
options?: Record<string, any> | undefined;
filter?: (source: Buffer, sourcePath: string) => boolean | undefined;
filename?:
| string
| ((
pathData: {
filename?: string | undefined;
},
assetInfo?: import("webpack").AssetInfo | undefined,
) => string)
| undefined;
}[];
Default: undefined
Allows to setup default minimizer.
You can use either a single minimizer object or an array of them.
imageminwebpack.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,
loader: ImageMinimizerPlugin.loader,
enforce: "pre",
options: {
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
},
},
],
},
};
For more information and supported options please read here.
generatorType:
type generator = {
implementation: TransformerFunction<T>;
options?: BasicTransformerOptions<T>;
filter?: FilterFn | undefined;
filename?: string | FilenameFn | undefined;
preset?: string | undefined;
type?: "import" | "asset" | undefined;
}[];
Default: undefined
Allow to setup default generators. This is useful for creating new image formats (e.g., webp, avif, etc.) from existing images.
imageminThe following example demonstrates how to configure a generator that converts images to the webp format using imagemin.
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,
loader: ImageMinimizerPlugin.loader,
enforce: "pre",
options: {
generator: [
{
preset: "webp",
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
plugins: ["imagemin-webp"],
},
},
],
},
},
],
},
};
This setup will automatically generate .webp versions of the original assets during the build process. For more information and supported options please read here.
severityErrorType:
type severityError = string;
Default: 'error'
Allows to choose how errors are displayed during image optimization.
Сan have the following values:
'off' - Suppresses errors and warnings'warning' - Emits warnings instead errors'error' - Emits 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"],
},
},
},
],
},
],
},
};
imageminNormalizeConfig(config)The function normalizes configuration (converts plugins names and options to Functions) for using in imagemin package directly.
const { imageminNormalizeConfig } = require("image-minimizer-webpack-plugin");
const imagemin = require("imagemin");
/*
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] }
]
}
*/
const imageminConfig = await imageminNormalizeConfig({
plugins: ["jpegtran", ["pngquant", { quality: [0.6, 0.8] }]],
});
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/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 = {
optimization: {
minimizer: [
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [["jpegtran", { progressive: true }]],
},
// Only apply this one to files equal to or over 8192 bytes
filter: (source) => {
if (source.byteLength >= 8192) {
return true;
}
return false;
},
},
}),
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [["jpegtran", { progressive: false }]],
},
// Only apply this one to files under 8192
filter: (source) => {
if (source.byteLength < 8192) {
return true;
}
return false;
},
},
}),
],
},
};
webp imagesYou can generate modern image formats like webp alongside optimized originals using the generator option.
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
generator: [
{
// You can apply generator using `?as=webp`, you can use any name and provide more options
preset: "webp",
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
plugins: ["imagemin-webp"],
},
},
],
}),
],
},
};
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.squooshMinify,
},
generator: [
{
// You can apply generator using `?as=webp`, you can use any name and provide more options
preset: "webp",
implementation: ImageMinimizerPlugin.squooshGenerate,
options: {
encodeOptions: {
webp: {
quality: 90,
},
},
},
},
],
}),
],
},
};
webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify,
},
generator: [
{
// You can apply generator using `?as=webp`, you can use any name and provide more options
preset: "webp",
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
encodeOptions: {
webp: {
quality: 90,
},
},
},
},
],
}),
],
},
};
webp images from copied assetsYou can use the generator feature to create modern image formats (like webp) from static assets copied using copy-webpack-plugin.
webpack.config.js
const CopyPlugin = require("copy-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
},
},
generator: [
{
type: "asset",
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
plugins: ["imagemin-webp"],
},
},
],
}),
],
},
plugins: [new CopyPlugin({ patterns: ["images/**/*.png"] })],
};
webpack.config.js
const CopyPlugin = require("copy-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.squooshMinify,
},
generator: [
{
type: "asset",
implementation: ImageMinimizerPlugin.squooshGenerate,
options: {
encodeOptions: {
webp: {
quality: 90,
},
},
},
},
],
}),
],
},
plugins: [new CopyPlugin({ patterns: ["images/**/*.png"] })],
};
webpack.config.js
const CopyPlugin = require("copy-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify,
},
generator: [
{
type: "asset",
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
encodeOptions: {
webp: {
quality: 90,
},
},
},
},
],
}),
],
},
plugins: [new CopyPlugin({ patterns: ["images/**/*.png"] })],
};
We welcome contributions! If you’re interested in helping improve this plugin, please take a moment to read our contributing guidelines.
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.node.NodeEnvironmentPlugin()
컴파일러에 Node.js 스타일의 파일 시스템을 적용합니다.
컴파일러에 영향을 주는 플러그인입니다.
MemoryCachePlugin()
모듈이 메모리에 캐시되는 컴파일러에 캐시를 추가합니다.
ProgressPlugin(handler)
컴파일러에 훅을 하여 진행 정보를 추출합니다. handler는 function(percentage, message)라는 서명이 있어야 합니다. Percentage는 0과 1 사이의 값으로 불립니다. 0은 시작, 1은 끝을 나타냅니다.
RecordIdsPlugin()
레코드로부터 청크 아이디와 모듈을 저장하고 복원합니다.
컴파일에 엔트리 청크를 포함하는 플러그인입니다.
EntryPlugin(context, entry, options)
컴파일에 엔트리 청크를 추가합니다. 청크의 이름은 options.name이고 오직 하나의 모듈만 포함합니다(의존성 추가). 모듈은 context (절대 경로)의 entry에서 확인됩니다.
PrefetchPlugin(context, request)
병렬 컴파일을 더 사용하기 위해서 의존성과 request를 프리페치합니다. 어떤 청크도 생성되지 않습니다. 모듈은 context (절대 경로)의 request에서 확인됩니다.
JsonpTemplatePlugin(options)
청크는 JSONP-calls로 래핑되어 있습니다. 로딩 알고리즘은 엔트리 청크에 포함이 됩니다. <script> 태그를 추가함으로써 청크를 로드합니다.
options는 출력 옵션입니다.
options.jsonpFunction은 JSONP 함수입니다.
options.publicPath는 청크를 로딩하기 위한 경로로 사용됩니다.
options.chunkFilename는 청크가 예상되는 파일 이름 이름입니다.
node/NodeTemplatePlugin(options)
청크는 번들 모듈을 내보내는 Node.js 모듈로 래핑되어 있습니다. 엔트리 청크는 청크를 요구함으로써 로드됩니다.
options는 출력 옵션입니다.
options.chunkFilename는 청크를 로딩하기 위한 경로로 사용됩니다.
LibraryTemplatePlugin(name, target)
엔트리 청크들은 type 유형의 name 라이브러리로부터 꾸며집니다.
webworker/WebWorkerTemplatePlugin(options)
청크는 importScripts에 의해 로드됩니다. 그렇지 않다면 JsonpTemplatePlugin과 비슷합니다.
options은 출력 옵션입니다.
// @sourceURL로 주석이 달린 eval로 각각의 모듈을 래핑함으로써 모듈 템플릿을 꾸밉니다.
SourceMapDevToolPlugin(sourceMapFilename, sourceMappingURLComment, moduleFilenameTemplate, fallbackModuleFilenameTemplate)
각 청크에 대한 소스맵을 생성함으로써 템플릿들을 꾸밉니다.
sourceMapFilename은 소스맵의 파일 이름 템플릿입니다. [hash], [name], [id], [file] 과 [filebase]는 교체되었습니다. 만약에 인자가 없으면, 소스맵은 DataUrl로 인라인 될 것입니다.
HotModuleReplacementPlugin(options)
Hot module replacement 대한 지원을 추가합니다. 런타임 코드를 추가한 템플릿을 꾸밉니다. `module.hot' API를 추가합니다.
options.hotUpdateChunkFilename은 hot 업데이트 청크 파일 이름입니다.
options.hotUpdateMainFilename은 hot 업데이트 매니페스트 파일 이름입니다.
options.hotUpdateFunction는 hot 업데이트의 JSON 함수 이름입니다.
모듈의 소스 코드에 영향을 미치는 플러그인입니다.
webpack_public_path, webpack_require, webpack_modules 과 webpack_chunk_load에 접근할 수 있도록 설정합니다. require.valueOf와 require.onError가 다른 플러그인으로 처리되지 않도록 합니다.
현재는 쓸모가 없습니다. 다른 모듈 로더과의 호환성을 보장합니다.
파서에 의해 발사된 훅을 사용함으로써 dead branch를 추가로 제거를 가능하게 하려고 if (...)문과 삼항 연산자를 평가하여 true/false로 바꾸려고 시도합니다.
프로덕션 모드에는 dead branch와 관련하여 여러 최적화 들이 있습니다.
Webpack은 조건문을 평가하려고 할 것입니다. 만약 성공한다면 dead branch가 제거됩니다. Webpck은 컴파일러가 알지 못하는 한 상수 폴딩을 할 수 없습니다. 다음 예시를 봅시다.
import { calculateTax } from './tax';
const FOO = 1;
if (FOO === 0) {
// dead branch
calculateTax();
}
위의 예시에서, webpack은 branch를 자를 수 없지만, Terser는 할 수 있습니다. 그러나 만약 FOO가 DefinePlugin 을 사용하면, webpack은 성공할 것입니다.
import { calculateTax } from './tax';도 제거된다는 점을 언급해야 합니다. 왜냐하면 calculateTax() 호출이 dead branch에 있어 제거되었기 때문입니다.
ProvidePlugin(name, request)
만약에 모듈에서 name이 사용되는 경우는 require(<request>)에 의해 로드된 모듈에 의해서 채워집니다.
NodeStuffPlugin(options, context)
Node.js 모듈에서는 일반적으로 사용할 수 있는 항목을 제공합니다.
또한, module을 사용하는 경우에는 일부의 Node.js 항목으로 채워지도록 합니다.
require.js에서는 일반적으로 사용할 수 있는 항목을 제공합니다.
require[js].config는 제거됩니다. require.version은 0.0.0입니다. requirejs.onError는 require.onError에 매핑이 됩니다.
node/NodeSourcePlugin(options)
이 모듈은 Node.js 환경이 아니면 사용할 수 없는 Node.js의 내용을 추가합니다.
사용되는 경우에는 process, console, Buffer와 glo에 대한 polyfills을 추가해야 합니다.
node/NodeTargetPlugin()
만약 Node.js 환경에서 번들을 실행하는 경우에는 플러그인을 사용해야 합니다.
만약 네이티브 모듈이 번들 되어있더라도 올바르게 로드되도록 보장합니다.
dependencies/AMDPlugin(options)
AMD 스타일의 define과 require 모듈을 제공합니다. 또한, require.amd, define.amd 와 webpack_amd_options## 를 파라미터로 전달된 options에 바인딩합니다.
dependencies/CommonJsPlugin
CommonJs 스타일의 require 모듈을 제공합니다.
dependencies/RequireContextPlugin(modulesDirectories, extensions)
require.content를 제공합니다. modulesDirectories와 extensions 파라미터는 파일에 대한 요청을 대체할 수 있는 것을 찾는 데 사용됩니다. 리졸버에 제공하는 것과 동일한 배열을 제공하는 것이 유용합니다.
dependencies/RequireEnsurePlugin()
require.ensure를 제공합니다.
dependencies/RequireIncludePlugin()
require.include를 제공합니다.
DefinePlugin(definitions)
식별자에 대해 상수를 정의합니다.
definitions은 객체입니다.
webpack.optimize 네임스페이스 아래의 모든 플러그인은 mode 가 'none'으로 설정된 경우에만 사용해야 합니다. 그렇지 않다면 플러그인은 두 번 적용되어야 합니다.
optimize/LimitChunkCountPlugin(options)
병합 청크의 제한된 청크 수는 `options.maxChunks'보다 작습니다.
각 청크에 대한 오버헤드는 options.chunkOverhead 또는 기본값인 10000에 의해 제공됩니다. 엔트리 청크의 크기는 options.entryChunkMultiplicator (또는 10)에 의해 곱해집니다.
전체적인 크기를 가장 많이 줄인 청크가 첫 번째로 병합됩니다. 만약 여러 조합이 같으면 병합된 크기가 작은 것이 선택됩니다.
optimize/MergeDuplicateChunksPlugin()
같은 모듈의 청크가 병합됩니다.
optimize/RemoveEmptyChunksPlugin()
모든 부모 청크에 포함된 모듈은 청크로부터 제거됩니다.
optimize/MinChunkSizePlugin(minChunkSize)-
각 청크의 최소 크기가 minChunkSize가 될 때까지 청크를 병합합니다.
ModuleConcatenationPlugin page에 대한 구체적인 내용을 확인해보세요.
optimize/FlagIncludedChunksPlugin()
청크에 포함된 청크의 청크 아이디를 추가합니다. 불필요한 청크 로드를 제거할 수 있습니다.
optimize/RealContentHashPlugin()
optimization.realContentHash 옵션이 활성화 될 때, webpack은 내부적으로 RealContentHashPlugin을 컴파일러에 추가합니다.
RealContentHashPlugin은 해시 업데이트를 커스터마이징할 수 있는 훅인 updateHash 5.8.0+를 제공합니다.
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) => {
// 이곳에서 원하는데로 해시를 계산할 수 있습니다.
});
});
This plugin uses JSON.stringify() to minify your JSON files during the build process.
To begin, you'll need to install json-minimizer-webpack-plugin:
npm install json-minimizer-webpack-plugin --save-dev
or
yarn add -D json-minimizer-webpack-plugin
or
pnpm add -D json-minimizer-webpack-plugin
Then add the plugin to your webpack configuration. For example:
webpack.config.js
const CopyPlugin = require("copy-webpack-plugin");
const JsonMinimizerPlugin = require("json-minimizer-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(),
],
},
};
Finally, run webpack using the method you normally use (e.g., via CLI or an npm script).
testType:
type test = string | RegExp | (string | RegExp)[];
Default: /\.json(\?.*)?$/i
Test to match files against.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
test: /\.foo\.json/i,
}),
],
},
};
includeType:
type include = string | RegExp | (string | RegExp)[];
Default: undefined
Files to include for minimization.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
include: /\/includes/,
}),
],
},
};
excludeType:
type exclude = string | RegExp | (string | RegExp)[];
Default: undefined
Files to exclude from minimization.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
exclude: /\/excludes/,
}),
],
},
};
minimizerOptionsType:
interface minimizerOptions {
space?: null | string | number;
replacer?: null | Function | (string | number)[];
}
Default: { replacer: null, space: null }
JSON.stringify() options.
module.exports = {
optimization: {
minimize: true,
minimizer: [
new JsonMinimizerPlugin({
minimizerOptions: {
space: "\t",
},
}),
],
},
};
We welcome all contributions! If you're new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.
코드를 작성할 때, 이미 필요한 것을 로드할 많은 코드 분할 지점을 추가했을 것입니다. 컴파일 후에 어떤 청크가 너무 작다는 것을 깨달을 것입니다. 이는 더 큰 HTTP 오버헤드를 만듭니다. LimitChunkCountPlugin은 청크를 합침으로써 그것들을 후속 처리할 수 있게 해줍니다.
new webpack.optimize.LimitChunkCountPlugin({
// Options...
});
다음의 옵션들이 지원됩니다.
number
청크의 최대 개수를 1보다 크거나 같도록 제한합니다. 1을 사용하는 것은 엔트리/메인 청크가 카운트에 포함될 때 추가적인 청크가 더해지는 것을 방지합니다.
webpack.config.js
const webpack = require('webpack');
module.exports = {
// ...
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 5,
}),
],
};
위의 지정된 청크 크기를 유지하는 것은 이 플러그인에서 구현하지 않습니다. MinChunkSizePlugin을 대신 사용하세요.
이 플러그인과 옵션은 CLI를 통해 호출될 수도 있습니다.
webpack --optimize-max-chunks 15
minChunkSize보다 작은 청크를 병합하여 청크 크기를 설정한 한계 이상으로 유지합니다.
new webpack.optimize.MinChunkSizePlugin({
minChunkSize: 10000, // 최소 문자 수
});
해당 플러그인과 플러그인 옵션은 CLI를 통해서도 실행할 수 있습니다.
webpack --optimize-min-chunk-size 10000
This plugin extracts CSS into separate files. It creates a CSS file for each JS file that contains CSS. It supports On-Demand-Loading of CSS and SourceMaps.
It builds on top of a new webpack v5 feature and requires webpack 5 to work.
Compared to the extract-text-webpack-plugin:
To begin, you'll need to install mini-css-extract-plugin:
npm install --save-dev mini-css-extract-plugin
or
yarn add -D mini-css-extract-plugin
or
pnpm add -D mini-css-extract-plugin
It's recommended to combine mini-css-extract-plugin with the css-loader
Then add the loader and the plugin to your webpack configuration. For example:
style.css
body {
background: green;
}
component.js
import "./style.css";
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
[!WARNING]
Note that if you import CSS from your webpack entrypoint or import styles in the initial chunk,
mini-css-extract-pluginwill not load this CSS into the page automatically. Please usehtml-webpack-pluginfor automatic generationlinktags or manually include a<link>tag in yourindex.htmlfile.
[!WARNING]
Source maps works only for
source-map/nosources-source-map/hidden-nosources-source-map/hidden-source-mapvalues because CSS only supports source maps with thesourceMappingURLcomment (i.e.//# sourceMappingURL=style.css.map). If you need setdevtoolto another value you can enable source maps generation for extracted CSS usingsourceMap: trueforcss-loader.
filenameType:
type filename =
| string
| ((pathData: PathData, assetInfo?: AssetInfo) => string);
Default: [name].css
This option determines the name of each output CSS file.
Works like output.filename
chunkFilenameType:
type chunkFilename =
| string
| ((pathData: PathData, assetInfo?: AssetInfo) => string);
Default: Based on filename
Specifying
chunkFilenameas afunctionis only available in webpack@5
This option determines the name of non-entry chunk files.
Works like output.chunkFilename
ignoreOrderType:
type ignoreOrder = boolean;
Default: false
Remove Order Warnings. See examples for more details.
insertType:
type insert = string | ((linkTag: HTMLLinkElement) => void);
Default: document.head.appendChild(linkTag);
Inserts the link tag at the given position for non-initial (async) CSS chunks
[!WARNING]
Only applicable for non-initial (async) chunks.
By default, the mini-css-extract-plugin appends styles (<link> elements) to document.head of the current window.
However in some circumstances it might be necessary to have finer control over the append target or even delay link elements insertion.
For example this is the case when you asynchronously load styles for an application that runs inside of an iframe.
In such cases insert can be configured to be a function or a custom selector.
If you target an iframe, make sure that the parent document has sufficient access rights to reach into the frame document and append elements to it.
stringAllows to setup custom query selector.
A new <link> element will be inserted after the found item.
webpack.config.js
new MiniCssExtractPlugin({
insert: "#some-element",
});
A new <link> tag will be inserted after the element with the ID some-element.
functionAllows to override default behavior and insert styles at any position.
⚠ Do not forget that this code will run in the browser alongside your application. Since not all browsers support latest ECMA features like
let,const,arrow function expressionand etc we recommend you to use only ECMA 5 features and syntax.⚠ The
insertfunction is serialized to string and passed to the plugin. This means that it won't have access to the scope of the webpack configuration module.
webpack.config.js
new MiniCssExtractPlugin({
insert(linkTag) {
const reference = document.querySelector("#some-element");
if (reference) {
reference.parentNode.insertBefore(linkTag, reference);
}
},
});
A new <link> tag will be inserted before the element with the ID some-element.
attributesType:
type attributes = Record<string, string>;
Default: {}
[!WARNING]
Only applies to non-initial (async) chunks.
If defined, the mini-css-extract-plugin will attach given attributes with their values on <link> element.
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
attributes: {
id: "target",
"data-target": "example",
},
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
[!NOTE]
It's only applied to dynamically loaded CSS chunks. If you want to modify
<link>attributes inside HTML file, please use html-webpack-plugin
linkTypeType:
type linkType = string | boolean;
Default: text/css
This option allows loading asynchronous chunks with a custom link type, such as <link type="text/css" ...>.
stringPossible values: text/css
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
linkType: "text/css",
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
booleanfalse disables the link type attribute entirely.
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"],
},
],
},
};
runtimeType:
type runtime = boolean;
Default: true
Allows to enable/disable the runtime generation. CSS will be still extracted and can be used for a custom loading methods. For example, you can use assets-webpack-plugin to retrieve them then use your own runtime code to download assets when needed.
false to skip.
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"],
},
],
},
};
experimentalUseImportModuleType:
type experimentalUseImportModule = boolean;
Default: undefined
Enabled by default if not explicitly enabled (i.e. true and false allow you to explicitly control this option) and new API is available (at least webpack 5.52.0 is required).
Boolean values are available since version 5.33.2, but you need to enable experiments.executeModule (not required from webpack 5.52.0).
Use a new webpack API to execute modules instead of child compilers, significantly improving performance and memory usage.
When combined with experiments.layers, this adds a layer option to the loader options to specify the layer of the CSS execution.
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// You don't need this for `>= 5.52.0` due to the fact that this is enabled by default
// Required only for `>= 5.33.2 & <= 5.52.0`
// Not available/unsafe for `<= 5.33.2`
experimentalUseImportModule: true,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
publicPathType:
type publicPath =
| string
| ((resourcePath: string, rootContext: string) => string);
Default: the publicPath in webpackOptions.output
Specifies a custom public path for the external resources like images, files, etc inside CSS.
Works like output.publicPath
stringwebpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "/public/path/to/",
},
},
"css-loader",
],
},
],
},
};
functionwebpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) =>
`${path.relative(path.dirname(resourcePath), context)}/`,
},
},
"css-loader",
],
},
],
},
};
emitType:
type emit = boolean;
Default: true
If true, emits a file (writes a file to the filesystem).
If false, the plugin will extract the CSS but will not emit the file.
It is often useful to disable this option for server-side packages.
esModuleType:
type esModule = boolean;
Default: true
By default, mini-css-extract-plugin generates JS modules that use the ES modules syntax.
There are some cases in which using ES modules is beneficial, like in the case of module concatenation and tree shaking.
You can enable a CommonJS syntax using:
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
esModule: false,
},
},
"css-loader",
],
},
],
},
};
defaultExportType:
type defaultExport = boolean;
Default: false
[!NOTE]
This option will work only when you set
namedExporttotrueincss-loader
By default, mini-css-extract-plugin generates JS modules based on the esModule and namedExport options in css-loader.
Using the esModule and namedExport options will allow you to better optimize your code.
If you set esModule: true and namedExport: true for css-loader mini-css-extract-plugin will generate only a named export.
Our official recommendation is to use only named export for better future compatibility.
But for some applications, it is not easy to quickly rewrite the code from the default export to a named export.
In case you need both default and named exports, you can enable this option:
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: {
defaultExport: true,
},
},
{
loader: "css-loader",
options: {
esModule: true,
modules: {
namedExport: true,
},
},
},
],
},
],
},
};
For production builds, it is recommended to extract the CSS from your bundle being able to use parallel loading of CSS/JS resources later on. This can be achieved by using the mini-css-extract-plugin, because it creates separate css files.
For development mode (including webpack-dev-server) you can use style-loader, because it injects CSS into the DOM using multiple and works faster.
Important: Do not use
style-loaderandmini-css-extract-plugintogether.
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== "production";
module.exports = {
module: {
rules: [
{
// If you enable `experiments.css` or `experiments.futureDefaults`, please uncomment line below
// type: "javascript/auto",
test: /\.(sa|sc|c)ss$/,
use: [
devMode ? "style-loader" : MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader",
],
},
],
},
plugins: [devMode ? [] : [new MiniCssExtractPlugin()]].flat(),
};
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",
],
},
],
},
};
⚠ Names of locals are converted to
camelCase.
⚠ It is not allowed to use JavaScript reserved words in CSS class names.
⚠ Options
esModuleandmodules.namedExportincss-loadershould be enabled.
styles.css
.foo-baz {
color: red;
}
.bar {
color: blue;
}
index.js
import { bar, fooBaz } from "./styles.css";
console.log(fooBaz, bar);
You can enable a ES module named export using:
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: "css-loader",
options: {
esModule: true,
modules: {
namedExport: true,
localIdentName: "foo__[name]__[local]",
},
},
},
],
},
],
},
};
publicPath option as functionYou can specify publicPath as a function to dynamically determine the public path based on each resource’s location relative to the project root or context.
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) =>
// publicPath is the relative path of the resource to the context
// e.g. for ./css/admin/main.css the publicPath will be ../../
// while for ./css/main.css the publicPath will be ../
`${path.relative(path.dirname(resourcePath), context)}/`,
},
},
"css-loader",
],
},
],
},
};
This plugin should not be used with style-loader in the loaders chain.
Here is an example to have both HMR in development and your styles extracted in a file for production builds.
(Loaders options left out for clarity, adapt accordingly to your needs.)
You should not use HotModuleReplacementPlugin plugin if you are using a webpack-dev-server.
webpack-dev-server enables / disables HMR using hot option.
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const webpack = require("webpack");
const devMode = process.env.NODE_ENV !== "production";
const plugins = [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? "[name].css" : "[name].[contenthash].css",
chunkFilename: devMode ? "[id].css" : "[id].[contenthash].css",
}),
];
if (devMode) {
// only enable hot in development
plugins.push(new webpack.HotModuleReplacementPlugin());
}
module.exports = {
plugins,
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader",
],
},
],
},
};
[!NOTE]
HMR is automatically supported in webpack 5. No need to configure it. Skip the following:
The mini-css-extract-plugin supports hot reloading of actual CSS files in development.
Some options are provided to enable HMR of both standard stylesheets and locally scoped CSS or CSS modules.
Below is an example configuration of mini-css for HMR use with CSS modules.
You should not use HotModuleReplacementPlugin plugin if you are using a webpack-dev-server.
webpack-dev-server enables / disables HMR using hot option.
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const webpack = require("webpack");
const plugins = [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? "[name].css" : "[name].[contenthash].css",
chunkFilename: devMode ? "[id].css" : "[id].[contenthash].css",
}),
];
if (devMode) {
// only enable hot in development
plugins.push(new webpack.HotModuleReplacementPlugin());
}
module.exports = {
plugins,
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {},
},
"css-loader",
],
},
],
},
};
To minify the output, use a plugin like css-minimizer-webpack-plugin.
webpack.config.js
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-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 o keep JS minimizers and add CSS minimizer:
// `...`,
new CssMinimizerPlugin(),
],
},
};
optimization.minimize option to true.The runtime code detects already added CSS via <link> or <style> tags and avoids duplicating CSS loading.
href of the <link> tag has to match the URL that will be used for loading the CSS chunk.data-href attribute can be used for both <link> and <style> elements.data-href must be used.The CSS can be extracted in one CSS file using optimization.splitChunks.cacheGroups with the type "css/mini-extract".
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"],
},
],
},
};
Note that type should be used instead of test in Webpack 5, or else an extra .js file can be generated besides the .css file. This is because test doesn't know which modules should be dropped (in this case, it won't detect that .js should be dropped).
You may also extract the CSS based on the webpack entry name. This is especially useful if you import routes dynamically but want to keep your CSS bundled according to entry. This also prevents the CSS duplication issue one had with the ExtractTextPlugin.
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
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) => chunk.name === "foo",
enforce: true,
},
barStyles: {
type: "css/mini-extract",
name: "styles_bar",
chunks: (chunk) => chunk.name === "bar",
enforce: true,
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
With the filename option you can use chunk data to customize the filename.
This is particularly useful when dealing with multiple entry points and wanting to get more control out of the filename for a given entry point/chunk.
In the example below, we'll use filename to output the generated css into a different directory.
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: ({ chunk }) => `${chunk.name.replace("/js/", "/css/")}.css`,
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
For long term caching use filename: "[contenthash].css". Optionally add [name].
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
chunkFilename: "[id].[contenthash].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
For projects where CSS ordering has been mitigated through consistent use of scoping or naming conventions, such as CSS Modules, the css order warnings can be disabled by setting the ignoreOrder flag to true for the plugin.
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
ignoreOrder: true,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
Switch themes by conditionally loading different SCSS variants with query parameters.
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: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: "@use 'dark-theme/vars' as vars;",
},
},
],
},
{
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: "@use 'light-theme/vars' as vars;",
},
},
],
},
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
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) {
console.log(`CHANGE THEME - ${newTheme}`);
const themeElement = document.querySelector("#theme");
if (themeElement) {
themeElement.remove();
}
if (themes[newTheme]) {
console.log(`THEME ALREADY LOADED - ${newTheme}`);
document.head.appendChild(themes[newTheme]);
return;
}
if (newTheme === "dark") {
console.log(`LOADING THEME - ${newTheme}`);
import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => {
themes[newTheme] = document.querySelector("#theme");
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>
If you'd like to extract the media queries from the extracted CSS (so mobile users don't need to load desktop or tablet specific CSS anymore) you should use one of the following plugins:
The mini-css-extract-plugin provides hooks to extend it to your needs.
SyncWaterfallHook
Called before inject the insert code for link tag. Should return a string
MiniCssExtractPlugin.getCompilationHooks(compilation).beforeTagInsert.tap(
"changeHref",
(source, varNames) =>
Template.asString([
source,
`${varNames.tag}.setAttribute("href", "/plugins/mini-css-extract-plugin/));`,
]),
);
We welcome all contributions! If you're new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.
과거에 번들링을 할 때 webpack의 절충점 중 하나는 번들의 각 모듈이 개별 함수 클로저에 의해 래핑된다는 점이었습니다. 이러한 래퍼 함수는 브라우저에서 자바스크립트의 실행을 느리게 만들었습니다. 이와 달리, Closure Comiler와 RollupJS와 같은 도구는 모든 모듈을 하나의 클로저로 호이스팅 하거나 연결하여 코드가 브라우저에서 더 빠른 실행 시간을 갖게 했습니다.
이 플러그인은 위의 내용과 같은 연결 동작이 webpack에서 가능하게 해줍니다. 기본적으로 이 플러그인은 production mode에서는 이미 가능하고 나머지에서는 아직 가능하지 않습니다. 만약 생산 mode 최적화를 무효로 해야 하는 경우, optimization.concatenateModules 옵션을 false로 설정하세요. 다른 모드에서 연결 동작을 가능하게 하고 싶을 경우, ModuleConcatenationPlugin을 수동으로 설정하거나 optimization.concatenateModules 옵션을 사용하세요.
new webpack.optimize.ModuleConcatenationPlugin();
이 연결 동작은 “범위 호이스팅” 이라고 불립니다.
범위 호이스팅은 특별히 ECMAScript Module 문법에서 사용 가능하도록 만들어진 형태입니다. 이로 인해 webpack은 현재 사용 중인 모듈의 종류와 다른 여러 조건에 따라 평범한 번들링으로 퇴화할 수도 있습니다.
글에서 설명하듯이 webpack은 부분적인 범위 호이스팅을 시도합니다. 이는 모듈을 하나의 범위로 합치지만 모든 경우에 합치지는 못합니다. 만약 webapck이 모듈을 합칠 수 없다면 두 가지 대안은 Prevent와 Root 입니다. Prevent는 모듈이 반드시 그 자신의 범위 안에 있어야 한다는 것을 의미합니다. Root는 새로운 모듈 그룹이 생성될 것이라는 의미입니다. 다음의 조건이 결과를 결정합니다.
| Condition | Outcome |
|---|---|
| Non ES6 Module | Prevent |
| Non Import로 가져옴 | Root |
| 다른 청크에서 가져옴 | Root |
| 다수의 다른 모듈 그룹에서 가져옴 | Root |
import()로 가져옴 | Root |
ProvidePlugin의 영향을 받거나 module 사용 | Prevent |
| HMR 허용 | Root |
eval() 사용 | Prevent |
| 다수의 청크 | Prevent |
| "cjs-module"로부터 * 내보내기 | Prevent |
아래의 자바스크립트 의사코드는 이 알고리즘을 설명합니다.
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 config를 사용할 경우 stats 객체에 다음을 추가하세요.
module.exports = {
//...
stats: {
// Display bailout reasons
optimizationBailout: true,
},
};
Webpack에는 많은 플러그인 인터페이스가 있습니다. Webpack 자체에 있는 대부분의 기능은 플러그인 인터페이스를 사용합니다. 이런점이 webpack을 유연하게 만듭니다.
| 이름 | 설명 |
|---|---|
BannerPlugin | 생성된 청크의 상단에 배너 추가 |
ChunksWebpackPlugin | 번들을 제공하기 위해 엔트리 포인트 및 청크 관계가 포함된 HTML 파일 생성 |
CommonsChunkPlugin | 청크 간에 공유되는 공통 모듈 추출 |
CompressionWebpackPlugin | Content-Encoding으로 제공할 압축된 버전의 애셋 준비 |
ContextReplacementPlugin | require 표현식의 유추된 컨텍스트 재정의 |
CopyWebpackPlugin | 개별 파일 또는 전체 디렉터리를 빌드 디렉터리에 복사 |
DefinePlugin | 컴파일 타임에 전역 변수 선언 |
DllPlugin | 빌드 시간을 단축시키기 위해 번들 분할 |
EnvironmentPlugin | process.env 키에서 DefinePlugin을 사용하는 약어 |
EslintWebpackPlugin | webpack을 위한 ESLint 플러그인 |
HotModuleReplacementPlugin | Hot Module Replacement (HMR) 활성화 |
HtmlWebpackPlugin | 번들을 제공하기 위한 HTML 파일을 쉽게 생성 |
IgnorePlugin | 번들에서 특정 모듈 제외 |
LimitChunkCountPlugin | 청킹을 더 잘 제어하기 위한 청킹의 최소/최대 제한 설정 |
MinChunkSizePlugin | 청크 크기를 지정한 제한 이상으로 유지 |
MiniCssExtractPlugin | CSS파일을 필요로하는 JS파일만 CSS파일을 생성 |
NoEmitOnErrorsPlugin | 컴파일 오류가 있는 경우 방출 단계를 건너뜀 |
NormalModuleReplacementPlugin | 정규식과 일치하는 리소스 교체 |
NpmInstallWebpackPlugin | 개발단계에서 누락된 디펜던시 자동 설치 |
ProgressPlugin | 컴파일 진행률 보고 |
ProvidePlugin | import 또는 require 사용없이 모듈 사용 |
SourceMapDevToolPlugin | 소스맵을 세밀하게 제어 |
EvalSourceMapDevToolPlugin | eval 소스맵을 세밀하게 제어 |
SvgChunkWebpackPlugin | 엔트리 포인트의 의존성을 기반으로 SVGO에 의해 최적화된 SVG 스프라이트 생성 |
TerserPlugin | Terser를 사용하여 JS 압축 |
더 많은 써드 파티 플러그인을 찾고 싶다면, awesome-webpack을 참고하세요.
ModuleFederationPlugin을 사용하면 런타임에 다른 독립 빌드와 함께 모듈을 제공하거나 사용할 수 있습니다.
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
// 여러 옵션을 타입스크립트로 작성합니다.
runtime: string | false,
}),
],
};
특정한 이름으로 새로운 런타임 청크를 만듭니다.
webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
runtime: 'my-runtime-name',
}),
],
};
설정의 'shared' 키를 사용하면 모듈 연합 사이에 공유되는 라이브러리를 정의할 수 있습니다. 패키지 이름은 package.json의 'dependencies' 섹션에 있는 이름과 동일합니다. 그러나 기본적으로 webpack은 라이브러리의 루트 레벨만 공유합니다.
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
// date-fns를 공유 모듈로 추가합니다.
shared: ['date-fns'],
}),
],
};
따라서 응용 프로그램에서 다음과 같은 작업을 수행할 수 있습니다.
import { format } from 'date-fns';
format(new Date(2014, 1, 11), 'MM/dd/yyyy');
그리고 webpack은 date-fns를 공유 라이브러리로 정의하는 모든 모듈 연합 사이에 date-fns를 자동으로 공유합니다.
그러나 패키지의 루트 레벨에 없는 항목(예: date-fns/locale/en-GB/index.js)에 액세스하려면 '공유' 설정에서 패키지 이름에 /를 추가해야 합니다.
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
// date-fns를 공유 모듈로 추가합니다.
// 패키지의 모든 파일이 공유됩니다
shared: ['date-fns/'],
}),
],
};
The / 구문을 사용하면 패키지의 모든 파일에 액세스할 수 있습니다. 그러나 특히 개발 모드에서는 성능에 영향을 미치므로 필요한 경우에만 사용해야 합니다.
공유 라이브러리의 버전을 지정하는 세 가지 방법이 있습니다.
이 구문을 사용하면 패키지 이름만 있는 라이브러리를 공유할 수 있습니다. 이 접근 방식은 프로토타이핑에 적합하지만 react 및 react-dom과 같은 라이브러리에 추가 요구 사항이 필요하기 때문에 대규모 프로덕션 환경으로 확장할 수 없습니다.
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
// lodash를 공유 모듈로 추가합니다.
// package.json으로부터 버전을 추론합니다.
// 필수 버전을 확인하지 않습니다.
// 그래서 항상 발견된 더 높은 버전을 사용합니다.
shared: ['lodash'],
}),
],
};
이 구문을 사용하면 패키지 이름을 키로 정의하고 버전(semver)을 값으로 정의할 수 있는 각 공유 라이브러리를 보다 세부적으로 제어할 수 있습니다.
module.exports = {
plugins: [
new ModuleFederationPlugin({
shared: {
// lodash를 공유 모듈로 추가합니다.
// package.json 으로부터 버전을 추론합니다.
// 4.17 이상 5 미만의 버전 중 최상위 버전을 사용하게 됩니다.
lodash: '^4.17.0',
},
}),
],
};
이 구문을 사용하면 각 공유 패키지에 힌트를 추가로 제공할 수 있습니다. 패키지의 이름을 키로, 공유 동작을 수정하기 위한 힌트를 포함한 객체를 값으로 정의하여 제공할 수 있습니다.
const deps = require('./package.json').dependencies;
module.exports = {
plugins: [
new ModuleFederationPlugin({
shared: {
// react를 공유 모듈로 추가합니다.
react: {
requiredVersion: deps.react,
singleton: true,
},
},
}),
],
};
eagerboolean
이 힌트를 사용하면 webpack이 비동기식 요청을 통해 라이브러리를 가져오는 대신 제공된 모듈이나 대체 모듈을 직접 포함할 수 있습니다. 즉, 초기 청크에서 이 공유 모듈을 사용할 수 있습니다. 또한 이 힌트가 활성화되면 제공된 모든 모듈과 대체 모듈이 항상 다운로드된다는 점에 주의해야 합니다.
importfalse | string
제공된 모듈은 공유 유효범위에 배치되어야 합니다. 이 제공된 모듈은 공유 유효범위에 공유 모듈이 없거나 버전이 유효하지 않은 경우 대체 모듈 역할도 합니다. (이 힌트의 값은 기본적으로 프로퍼티 이름으로 설정됩니다.)
packageNamestring
설명 파일에서 필요한 버전을 결정하는 데 사용되는 패키지 이름입니다. ‘packageName’은 요청으로부터 패키지 이름을 자동으로 결정할 수 없는 경우에만 필요합니다.
requiredVersionfalse string
이 필드는 필수 패키지 버전을 지정합니다. "^1.2.3"과 같은 시멘틱 버전 관리를 허용합니다. 또한 버전이 URL로 제공되는 경우(예: "git+ssh://git@github.com:foo/bar.git#v1.0.0") 버전을 검색합니다.
shareKeystring
요청된 공유 모듈은 공유 유효범위에서 ‘shareKey’ 키 안에서 조회됩니다.
shareScopestring
공유 범위의 이름입니다.
singletonboolean
‘singleton’은 공유 범위에서 단일 버전의 공유 모듈만 허용합니다.(기본적으로 비활성화됨) 일부 라이브러리는 전역 내부 상태를 사용합니다.(예: react, react-dom) 따라서 한 번에 하나의 라이브러리 인스턴스만 실행하는 것이 중요합니다.
공유 범위에 동일한 종속성을 갖는 여러 버전이 있는 경우, 가장 높은 시멘틱 버전이 사용됩니다.
strictVersionboolean
‘strictVersion’을 사용하면 버전이 유효하지 않은 경우 webpack이 공유 모듈을 거부할 수 있습니다(로컬 fallback 모듈을 사용할 수 있고 공유 모듈이 singleton이 아닌 경우 기본값은 true로 설정되고, 그렇지 않으면 false로 설정되며 필수 버전이 지정되지 않은 경우 효과가 없습니다). 필요한 버전이 없으면 런타임 오류가 발생합니다.
versionfalse | string
제공된 모듈의 버전입니다. Webpack이 일치하는 낮은 버전을 대체할 수 있지만, 더 높은 버전은 대체할 수 없습니다.
Webpack은 기본적으로 디펜던시의 package.json 파일에 있는 버전을 사용합니다.
module.exports = {
plugins: [
new ModuleFederationPlugin({
// vue를 공유 모듈로 추가합니다.
// package.json 으로부터 버전을 추론합니다.
// 항상 공유 버전을 사용하지만 공유된 vue가 2.6.5 미만 또는 3 이상 버전인 경우 경고를 출력합니다.
shared: {
vue: {
requiredVersion: '^2.6.5',
singleton: true,
},
},
}),
],
};
module.exports = {
plugins: [
new ModuleFederationPlugin({
// vue를 공유 모듈로 추가합니다.
// 제공된 로컬 버전이 없습니다.
// 공유된 vue가 2.6.5 미만 또는 3 이상 버전이면 경고를 내보냅니다.
shared: {
vue: {
import: false,
requiredVersion: '^2.6.5',
},
},
}),
],
};
module.exports = {
plugins: [
new ModuleFederationPlugin({
// vue를 공유 모듈로 추가합니다.
// 제공된 로컬 버전이 없습니다.
// 공유된 vue가 2.6.5 미만 또는 3 이상 버전이면 오류가 발생합니다.
shared: {
vue: {
import: false,
requiredVersion: '^2.6.5',
strictVersion: true,
},
},
}),
],
};
module.exports = {
plugins: [
new ModuleFederationPlugin({
shared: {
'my-vue': {
// 'my-vue' 가져오기로 참조할 수 있습니다.
import: 'vue', // 'vue' 패키지는 제공된 대체 모듈로 사용됩니다.
shareKey: 'shared-vue', // 'shared-vue'이름으로 공유된 모듈은 공유 유효범위에 배치됩니다.
shareScope: 'default', // 'default'로 공유 유효범위가 적용됩니다.
singleton: true, // 공유 모듈의 단일 버전만 허용됩니다.
strictVersion: true, // 버전이 유효하지 않을 때 공유 버전을 사용하지 말아야 합니다. fallback이 없는 Singleton 또는 모듈은 넘겨집니다. 그렇지 않으면 fallback이 사용됩니다.
version: '1.2.3', // 공유 모듈의 버전입니다.
requiredVersion: '^1.0.0', // 공유 모듈의 최소 버전 입니다.
},
},
}),
],
};
NoEmitOnErrorsPlugin을 사용하면 오류가 있을 때 애셋 방출을 피할 수 있습니다. 기본적으로 활성화되어 있으며, optimization.emitOnErrors를 사용하여 비활성화 할 수 있습니다.
webpack.config.js
module.exports = {
plugins: [new webpack.NoEmitOnErrorsPlugin()],
};
NormalModuleReplacementPlugin을 사용하면 resourceRegExp와 일치하는 리소스를 newResource로 교체할 수 있습니다. newResource가 상대적인 경우 이전 리소스를 기준으로 해결됩니다. newResource가 함수인 경우 제공된 리소스의 요청 속성을 덮어쓸 것으로 예상됩니다.
이는 빌드 간에 다른 동작을 허용하는 데 유용할 수 있습니다.
new webpack.NormalModuleReplacementPlugin(resourceRegExp, newResource);
resourceRegExp는 확인된 리소스가 아니라 코드에 작성한 요청에 대해 테스트 됩니다. 예를 들어, import sum from './sum' 코드가 있을 때 './sum.js' 대신 './sum'이 테스트에 사용됩니다.
또한 Windows를 사용할 때는 다른 폴더 구분 기호를 사용해야 합니다. 예를 들어 /src\/environments\/environment\.ts/는 Windows에서 작동하지 않기 때문에, /src[\\/]environments[\\/]environment\.ts/,를 대신 사용해야 합니다.
개발 환경용으로 빌드할 때 특정 모듈을 교체합니다.
some/path/config.development.module.js 설정 파일과 some/path/config.production.module.js에 프로덕션용 특수 버전이 있다면
프로덕션용으로 빌드할 때 다음 플러그인을 추가합니다.
new webpack.NormalModuleReplacementPlugin(
/some\/path\/config\.development\.js/,
'./config.production.js'
);
지정된 환경에 따른 조건부 빌드에 관한 내용입니다.
다른 빌드 대상에 대한 특정 값이 포함된 설정을 원한다고 가정해 보겠습니다.
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}`
);
if (resource.createData) {
resource.createData.request = resource.request;
}
}),
],
};
};
2개의 설정 파일을 생성합니다.
app/config-VERSION_A.js
export default {
title: 'I am version A',
};
app/config-VERSION_B.js
export default {
title: 'I am version B',
};
그다음 정규 표현식에서 찾고 있는 키워드를 사용하여 해당 설정을 가져옵니다.
import config from 'app/config-APP_TARGET';
console.log(config.title);
이제 빌드하려는 대상에 따라 올바른 설정을 가져올 수 있습니다.
npx webpack --env APP_TARGET=VERSION_A
=> 'I am version A'
npx webpack --env APP_TARGET=VERSION_B
=> 'I am version B'
일반 모듈의 요청을 프리페치하면 첫 번째에 import 또는 require가 발생하기 전에 요청을 확인하고 빌드합니다. 플러그인을 사용함으로써 성능을 높일 수 있습니다. 영리한 프리페칭 지점을 결정하기 위해, 먼저 빌드를 프로파일링 하세요.
new webpack.PrefetchPlugin([context], request);
context: 디렉터리에 대한 절대경로request: 일반 모듈에 대한 요청 문자열플러그인 실행 시간이 포함된 Chrome 프로필 파일을 생성합니다. 기본적으로 events.json 파일을 출력합니다. outputPath옵션을 사용하여 커스텀 파일 경로를 제공할 수 있습니다.
참고: ProfilingPlugin은 절대 경로만 사용합니다.
outputPath: 커스텀 출력 파일(json)의 절대 경로new webpack.debug.ProfilingPlugin();
outputPathnew webpack.debug.ProfilingPlugin({
outputPath: path.join(__dirname, 'profiling/profileEvents.json'),
});
프로필 파일을 보기 위해서는 다음과 같은 과정을 따릅니다.
ProfilingPlugin과 함께 webpack을 실행합니다.Performance 탭(이전 명칭 Timeline)으로 이동합니다.events.json)을 profiler로 끌어다 놓습니다.위와 같은 과정을 거치면 plugin당 timeline 통계와 호출들이 표시될 것입니다!
ProgressPlugin은 컴파일 도중에 진행 상황을 보고받을 방법을 자신이 원하는대로 정하는 방법을 제공합니다.
ProgressPlugin의 인스턴스를 만들고, 허용되는 여러 매개변수 중 하나를 제공하며, 기본 핸들러를 사용자 지정하는 데 사용할 수 있는 정적 메서드 createDefaultHandler도 있습니다.
function훅이 진행 상황을 보고할 때 호출될 handler 함수를 제공합니다. 함수 handler의 실행 인자:
percentage: 컴파일의 성공 확률을 나타내는 0과 1 사이의 숫자message: 현재 실행중인 훅에 대한 짧은 설명...args: 현재 실행 상황을 묘사하는 0개 이상의 추가적인 문자열const handler = (percentage, message, ...args) => {
// 예를 들어, 각 진행 메세지를 콘솔에 직접 출력
console.info(percentage, message, ...args);
};
new webpack.ProgressPlugin(handler);
objectProgressPlugin에 object를 제공할 때, 다음의 속성이 지원됩니다
activeModules (boolean = false): 활성화된 모듈의 수와 활성화된 모듈 하나를 진행 메세지로 보여줍니다.entries (boolean = true): 엔트리 수를 진행 메세지로 보여줍니다.handler (Providing function을 보세요)modules (boolean = true): 모듈 수를 진행 메세지로 보여줍니다.modulesCount (number = 5000): 시작할 모듈 수의 최솟값이며 modules 속성이 활성화되면 적용됩니다.profile (boolean = false): 진행 단계의 프로필 정보를 수집하도록 ProgressPlugin에게 알려줍니다.dependencies (boolean = true): 종속성 수를 진행 메세지로 보여줍니다.dependenciesCount (number = 10000): 시작할 종속성 수의 최솟값이며 dependencies 속성이 활성화되면 적용됩니다.percentBy (string = null: 'entries' | 'dependencies' | 'modules' | null): 진행률을 계산할 방법을 ProgressPlugin에게 알려줍니다.new webpack.ProgressPlugin({
activeModules: false,
entries: true,
handler(percentage, message, ...args) {
// 사용자 지정 로직
},
modules: true,
modulesCount: 5000,
profile: false,
dependencies: true,
dependenciesCount: 10000,
percentBy: null,
});
ProgressPlugin의 기본 핸들러가 요구 사항을 충족하지 않는 경우 정적 ProgressPlugin.createDefaultHandler 메서드를 사용하여 사용자 지정할 수 있습니다.
static createDefaultHandler: (
profile: undefined | null | boolean,
logger: WebpackLogger
) => (percentage: number, msg: string, ...args: string[]) => void;
기본적으로 진행률은 빌드된 모듈 수와 총 모듈 수를 기반으로 계산됩니다: built / total
총 모듈 수는 사전에는 알 수 없고 빌드를 거치면서 변합니다. 이는 부정확한 진행률을 야기할 수 있습니다.
이러한 문제를 해결하기 위해 ProgressPlugin은 마지막으로 알려진 총 모듈 수를 캐시하여 이 값을 다음 빌드 때 재사용합니다. 첫 번째 빌드는 데이터 값을 메모리에 캐시하지만 그 다음 빌드들은 이 값을 사용하고 업데이트합니다.
다중 구성된 엔트리 포인트가 있는 프로젝트들을 위한 설정에는
percentBy: 'entries'를 사용할 것을 추천합니다. 엔트리 포인트의 개수를 미리 알 수 있기 때문에 확률 계산은 더욱 정확해질 것입니다.
다음 훅은 ProgressPlugin에 진행 정보를 보고합니다.
Compiler
Compilation
모듈을 import 또는 require 할 필요 없이 자동으로 로드합니다.
new webpack.ProvidePlugin({
identifier: 'module1',
// ...
});
또는
new webpack.ProvidePlugin({
identifier: ['module1', 'property1'],
// ...
});
기본적으로, 모듈 해석 경로는 현재 폴더 (./**)와 node_modules입니다.
또한 전체 경로도 지정할 수 있습니다.
const path = require('path');
new webpack.ProvidePlugin({
identifier: path.resolve(path.join(__dirname, 'src/module1')),
// ...
});
모듈에서 자유 변수로 식별자를 만날 때마다 모듈이 자동으로 로드되고, 식별자가 로드된 모듈의 exports(혹은 지정된 exports를 돕기 위한 프로퍼티)로 채워집니다.
ES2015 모듈의 기본 export를 가져오려면 모듈의 기본 프로퍼티를 지정해야 합니다.
jquery를 자동으로 로드하려면 해당 노드 모듈에 노출되는 두 변수를 모두 가리킬 수 있습니다.
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
});
소스 코드 중 어느 것이라도 동일합니다.
// 모듈에서
$('#item'); // <= 동작합니다.
jQuery('#item'); // <= 이 또한 동작합니다.
// $는 모듈 "jquery" exports로 자동 설정되었습니다.
Angular는 jQuery가 존재하는지 찾기 위해 window.jQuery를 찾습니다. 소스 코드를 참고하세요.(https://github.com/angular/angular.js/blob/v1.5.9/src/Angular.js#L1821-L1823).
new webpack.ProvidePlugin({
'window.jQuery': 'jquery',
});
new webpack.ProvidePlugin({
_map: ['lodash', 'map'],
});
new webpack.ProvidePlugin({
Vue: ['vue/dist/vue.esm.js', 'default'],
});
이 플러그인을 사용하면 소스맵 생성을 더욱더 세밀하게 제어 할 수 있습니다. 이 플러그인은 devtool의 설정 옵션을 통해 자동으로 활성화됩니다.
new webpack.SourceMapDevToolPlugin(options);
다음과 같은 옵션이 제공됩니다.
test (string RegExp [string, RegExp]): 확장자에 따라 소스맵을 포함합니다. (기본값은 .js, .mjs 및 .css).
include (string RegExp [string, RegExp]): 값과 일치하는 경로의 소스맵을 포함합니다.
exclude (string RegExp [string, RegExp]): 값과 일치하는 모듈을 소스맵 생성에서 제외합니다.
filename (string): 소스맵의 파일 이름을 정의합니다 (값이 제공되지 않으면 인라인으로 설정됩니다).
append (string function false): 기존 애셋에 값을 추가합니다. 일반적으로 #sourceMappingURL 주석이 사용됩니다. [url]은 소스맵 파일의 URL로 대체됩니다. Webpack v4.36.0부터는 [chunk], [filename] 및 [contenthash]와 같은 경로 파라미터가 지원됩니다. false로 설정하면 값 추가가 비활성화됩니다.
버전 5.84.0부터 webpack은 경로와 애셋 정보 객체를 인수로 받아들이고 문자열을 반환하는 'append' 옵션을 허용합니다.
(pathData: PathData, assetInfo?: AssetInfo) => string;
moduleFilenameTemplate (string): output.devtoolModuleFilenameTemplate를 참고하세요.
fallbackModuleFilenameTemplate (string): 위 링크를 참고하세요.
namespace (string): output.devtoolNamespace를 참고하세요.
module = true (boolean): 로더가 소스맵을 생성해야 하는지 여부를 나타냅니다.
columns = true (boolean): 열 매핑을 사용해야 하는지 여부를 나타냅니다.
noSources = false (boolean): 소스의 내용이 소스맵에 포함되지 않도록 합니다.
publicPath (string): public path 접두사와 함께 절대 URL을 내보냅니다. (예: https://example.com/project/)
fileContext (string): 이 디렉터리를 기준으로 [file] 인수를 만듭니다.
sourceRoot (string): 소스맵의 sourceRoot 프로퍼티에 커스텀 값을 제공합니다.
debugIds (boolean): true이면 소스 및 소스맵에서 고유한 ID를 발행하여 여러 빌드에서 소스 맵을 식별하는 것이 간소화됩니다. 자세한 내용은 TC39 소스맵 디버깅 ID 제안서를 참고하세요.
fileContext 옵션은 ../../가 절대 [url]에 나타나지 않도록 상위 디렉터리에 소스맵을 저장하려는 경우에 유용합니다.
다음은 이 플러그인의 몇 가지 일반적인 사용 사례입니다.
다음 코드를 사용하여 설정 옵션 devtool: inline-source-map을 커스텀 플러그인 설정으로 동등하게 바꿀 수 있습니다.
module.exports = {
// ...
devtool: false,
plugins: [new webpack.SourceMapDevToolPlugin({})],
};
다음 코드는 vendor.js 번들 내 모듈의 소스맵을 제외합니다.
new webpack.SourceMapDevToolPlugin({
filename: '[file].map[query]',
exclude: ['vendor.js'],
});
소스맵의 URL을 설정하세요. 인증이 필요한 호스트에 호스팅하는 데 유용합니다.
new webpack.SourceMapDevToolPlugin({
append: '\n//# sourceMappingURL=https://example.com/sourcemap/[url]',
filename: '[file].map[query]',
});
소스맵이 상위 디렉터리에 저장되는 경우,
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
원래 청크(및 그 안에 가져온 모듈)는 webpack 내부 그래프에서 부모-자식 관계로 연결되었습니다. CommonsChunkPlugin은 중복되는 의존성을 피하고자 사용되었지만, 추가 최적화는 불가능했습니다.
webpack v4부터 optimization.splitChunks를 위해 CommonsChunkPlugin은 제거되었습니다.
즉시 사용 가능한 SplitChunksPlugin은 대부분의 사용자에게 잘 작동합니다.
초기 청크를 변경하면 HTML 파일이 프로젝트를 실행하기 위해 포함해야 하는 스크립트 태그에 영향을 미치기 때문에 기본적으로 on-demand 청크에만 영향을 미칩니다.
Webpack은 다음 조건에 따라 자동으로 청크를 분할합니다.
node_modules 폴더에 있는 경우마지막 두 가지 조건을 충족하려고 할 때 더 큰 청크가 선호됩니다.
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은 출처와 청크 이름을 사용하여 이름을 생성합니다(예: vendors~main.js). 이 옵션을 사용하면 생성된 이름에 사용할 구분 기호를 지정할 수 있습니다.
string = 'async' function (chunk) RegExp
이것은 최적화를 위해 선택될 청크를 나타냅니다. 문자열이 제공될 때 유효한 값은 all, async 및 initial입니다. all을 제공하는 것은 비동기 청크와 동기 청크 간에도 청크를 공유할 수 있다는 것을 의미하기 때문에 특히 강력할 수 있습니다.
대체 캐시 그룹(splitChunks.fallbackCacheGroup.chunks)에도 적용됩니다.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
// 모든 유형의 청크를 포함합니다.
chunks: 'all',
},
},
};
또는 더 많은 제어를 위한 기능을 제공할 수 있습니다. 반환 값은 각 청크를 포함할지 여부를 나타냅니다.
module.exports = {
//...
optimization: {
splitChunks: {
chunks(chunk) {
// `my-excluded-chunk`를 제외합니다.
return chunk.name !== 'my-excluded-chunk';
},
},
},
};
Webpack 버전 5.86.0 이상을 사용하는 경우 정규식을 전달할 수도 있습니다.
module.exports = {
//...
optimization: {
splitChunks: {
chunks: /foo/,
},
},
};
number = 30
on-demand 로드 시의 최대 병렬 요청 수입니다.
number = 30
엔트리 포인트의 최대 병렬 요청 수입니다.
[string] = ['javascript', 'unknown']
크기에 숫자를 사용할 때 적용되는 크기 유형을 설정합니다.
number = 1
모듈이 분할 전에 청크 간에 공유되어야 하는 최소 개수입니다.
boolean
maxSize로 분할된 부분의 이름을 만들 때 경로 정보가 노출되지 않도록 합니다.
number = 20000 { [index: string]: number }
생성할 청크의 최소 byte 크기입니다.
number { [index: string]: number }
청크를 생성하는 데 필요한 기본 청크(번들)의 바이트 단위의 줄어들 최소 크기입니다. 즉, 청크로 분할해도 기본 청크(번들)의 크기가 주어진 바이트만큼 줄어들지 않으면 splitChunks.minSize 값을 충족하더라도 분할되지 않습니다.
splitChunks.cacheGroups.{cacheGroup}.enforceSizeThresholdnumber = 50000
분할이 적용되고 기타 제한(minRemainingSize, maxAsyncRequests, maxInitialRequests)이 무시되는 임계 크기 값입니다.
splitChunks.cacheGroups.{cacheGroup}.minRemainingSizenumber = 0
splitChunks.minRemainingSize 옵션은 분할 후 남아있는 청크의 최소 크기가 제한을 초과하도록 하여 크기가 0인 모듈을 방지하기 위해 webpack 5에 도입되었습니다. 'development' 모드에서 기본값은 0입니다. 다른 경우 splitChunks.minRemainingSize는 기본적으로 splitChunks.minSize 값으로 설정되므로 심층 제어가 필요한 드문 경우를 제외하고는 수동으로 지정할 필요가 없습니다.
splitChunks.cacheGroups.{cacheGroup}.layerRegExp string function
모듈 계층별로 캐시 그룹에 모듈을 할당합니다.
number = 0
maxSize를 사용하면(캐시 그룹 optimization.splitChunks.cacheGroups[x].maxSize당 전역적으로 optimization.splitChunks.maxSize 또는 대체 캐시 그룹 optimization.splitChunks.fallbackCacheGroup.maxSize의 경우) webpack이 maxSize byte보다 큰 청크를 더 작은 부분으로 분할하도록 합니다. 분할된 크기는 최소 minSize(maxSize 다음)입니다.
알고리즘은 결정론적이며 모듈 변경은 로컬에만 영향을 미칩니다. 따라서 장기 캐싱을 사용할 때 사용할 수 있으며 기록이 필요하지 않습니다. maxSize는 힌트일 뿐이며 모듈이 maxSize 보다 크거나 분할이 minSize를 벗어날 때 위반될 수 있습니다.
청크에 이미 이름이 있는 경우 각 부분은 해당 이름에서 파생된 새 이름을 얻습니다. optimization.splitChunks.hidePathInfo의 값에 따라 첫 번째 모듈 이름이나 해시에서 파생된 키를 추가합니다.
maxSize 옵션은 HTTP/2 및 장기 캐싱과 함께 사용하기 위한 것입니다. 더 나은 캐싱을 위해 요청수가 증가합니다. 빠른 재구축을 위해 파일 크기를 줄이는 데도 사용할 수 있습니다.
number
maxSize와 마찬가지로 maxAsyncSize는 전역적으로(splitChunks.maxAsyncSize) 캐시 그룹(splitChunks.cacheGroups.{cacheGroup}.maxAsyncSize) 또는 대체 캐시 그룹(splitChunks.fallbackCacheGroup.maxAsyncSize)에 적용될 수 있습니다.
maxAsyncSize와 maxSize의 차이점은 maxAsyncSize가 on-demand 로딩 청크에만 영향을 미친다는 점입니다.
number
maxSize와 마찬가지로 maxInitialSize는 전역적으로(splitChunks.maxInitialSize) 캐시 그룹(splitChunks.cacheGroups.{cacheGroup}.maxInitialSize) 또는 대체 캐시 그룹(splitChunks.fallbackCacheGroup.maxInitialSize)에 적용될 수 있습니다.
maxInitialSize와 maxSize의 차이점은 maxInitialSize가 초기 로딩 청크 에만 영향을 미친다는 것입니다.
boolean = false function (module, chunks, cacheGroupKey) => string string
또한 splitChunks.cacheGroups.{cacheGroup}.name와 같이 각 캐시 그룹에 대해서도 사용 가능합니다.
이는 분할 청크의 이름입니다. false를 제공하면 청크의 이름이 동일하게 유지되므로 불필요하게 이름이 변경되지 않습니다. 프로덕션 빌드에 권장되는 값입니다.
문자열이나 함수를 제공하면 이름을 커스텀 할 수 있습니다. 항상 같은 문자열을 반환하는 문자열이나 함수를 지정하면 모든 공통 모듈과 vendor가 단일 청크로 병합됩니다. 이로 인해 초기 다운로드가 더 커지고 페이지 로드가 느려질 수 있습니다.
함수를 명시한 경우 청크의 이름을 선택하는 데 특히 유용한 chunk.name 속성(여기서 chunk는 chunks 배열의 요소)을 찾을 수 있습니다.
splitChunks.name이 엔트리 포인트이름과 일치하면 엔트리 포인트 청크 및 캐시 그룹이 단일 청크로 결합됩니다.
main.js
import _ from 'lodash';
console.log(_.join(['Hello', 'webpack'], ' '));
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
// 여기서 cacheGroupKey는 cacheGroup의 키로 `commons`입니다.
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}.usedExportsboolean = true
모듈이 export 할 파일의 이름을 수정(mangle)하고 사용하지 않는 export를 생략하고 보다 효율적인 코드를 생성하기 위해 어떤 export를 사용하는지 알아봅니다.
true인 경우 각 런타임에 대해 사용된 export를 분석하고, "global"인 경우 결합한 모든 런타임에 대해 전역적으로 export를 분석합니다.
캐시 그룹은 splitChunks.*의 모든 옵션을 상속 및(또는) 재정의할 수 있습니다. 그러나 test, priority 및 reuseExistingChunk는 캐시 그룹 수준에서만 구성할 수 있습니다. 기본 캐시 그룹을 비활성화하려면 false로 설정하세요.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
default: false,
},
},
},
};
splitChunks.cacheGroups.{cacheGroup}.prioritynumber = -20
모듈은 여러 캐시 그룹에 속할 수 있습니다. 최적화는 priority(우선순위)가 더 높은 캐시 그룹을 선호합니다. 기본 그룹은 커스텀 그룹이 더 높은 우선순위를 가질 수 있도록 음수 우선순위를 갖습니다(커스텀 그룹일 경우 기본값은 0입니다).
splitChunks.cacheGroups.{cacheGroup}.reuseExistingChunkboolean = true
현재 청크에 이미 기본 번들에서 분리된 모듈이 포함되어 있으면 새로 생성되는 대신 재사용됩니다. 이것은 청크의 파일 이름에 영향을 줄 수 있습니다.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
reuseExistingChunk: true,
},
},
},
},
};
splitChunks.cacheGroups.{cacheGroup}.typefunction RegExp string
모듈 유형별로 캐시 그룹에 모듈을 할당할 수 있습니다.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
json: {
type: 'json',
},
},
},
},
};
splitChunks.cacheGroups.{cacheGroup}.testfunction (module, { chunkGraph, moduleGraph }) => boolean RegExp string
캐시 그룹에 의해 선택되는 모듈을 제어합니다. 생략하면 모든 모듈이 선택됩니다. 이는 절대 경로 모듈 리소스 또는 청크 이름과 일치할 수 있습니다. 청크 이름이 일치하면 청크의 모든 모듈이 선택됩니다.
아래와 같이 {cacheGroup}.test에 기능을 제공합니다.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
svgGroup: {
test(module) {
// `module.resource`는 디스크에 있는 파일의 절대 경로를 포함합니다.
// 플랫폼 간 호환성을 위해 / 또는 \ 대신 `path.sep`을 사용합니다.
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 및 chunks 객체에서 어떤 정보를 사용할 수 있는지 확인하려면 콜백에 debugger; 문을 넣으면 됩니다. 그런 다음 디버그 모드에서 webpack 빌드를 실행하여 Chromium DevTools의 파라미터를 검사합니다.
아래는 {cacheGroup}.test에 RegExp를 제공한 경우입니다.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
// 플랫폼 간 호환성을 위한 경로 구분 기호로 `[\\/]`의 사용에 유의하세요.
test: /[\\/]node_modules[\\/]|vendor[\\/]analytics_provider|vendor[\\/]other_lib/,
},
},
},
},
};
splitChunks.cacheGroups.{cacheGroup}.filenamestring function (pathData, assetInfo) => string
초기 청크인 경우에만 파일 이름을 재정의할 수 있습니다.
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) => {
// 요구 사항에 따라 파일 이름 문자열을 생성하기 위해 pathData 객체를 사용하세요.
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}.enforceboolean = false
Webpack에 splitChunks.minSize, splitChunks.minChunks, splitChunks.maxAsyncRequests 및 splitChunks.maxInitialRequests 옵션을 무시하고 항상 이 캐시 그룹에 대한 청크를 생성하도록 지시합니다.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
enforce: true,
},
},
},
},
};
splitChunks.cacheGroups.{cacheGroup}.idHintstring
청크 ID에 대한 힌트를 설정합니다. 청크의 파일 이름에 추가됩니다.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
idHint: 'vendors',
},
},
},
},
};
// index.js
import('./a'); // 동적 import
// a.js
import 'react';
//...
결과: react를 포함하는 별도의 청크가 생성됩니다. import 호출에서 이 청크는 ./a를 포함하는 원래 청크와 병렬로 로드됩니다.
이유:
node_modules의 모듈을 포함합니다react가 30kb보다 큽니다이 이유는 무엇일까요? react는 애플리케이션 코드만큼 자주 변경되지 않을 것입니다. 별도의 청크로 이동하면 이 청크를 앱 코드와 별도로 캐시할 수 있습니다(청크 해시, 레코드, Cache-Control 또는 장기 캐시 접근 방식을 사용한다고 가정합니다).
// entry.js
// 동적 imports
import('./a');
import('./b');
// a.js
import './helpers'; // helpers의 크기는 40kb입니다
//...
// b.js
import './helpers';
import './more-helpers'; // more-helpers 또한 40kb의 크기를 가집니다
//...
결과: ./helpers와 이에 대한 모든 의존성을 포함하는 별도의 청크가 생성됩니다. import 호출에서 이 청크는 원래 청크와 병렬로 로드됩니다.
이유:
helpers는 30kb보다 큽니다helpers의 내용을 각 청크에 넣으면 코드가 두 번 다운로드됩니다. 별도의 청크를 사용하면 한 번만 발생합니다. 우리는 추가 요청 비용을 지불하며 이는 절충안으로 간주할 수 있습니다. 그렇기 때문에 최소 크기는 30kb입니다.
엔트리 포인트 간에 공유되는 모든 코드를 포함하는 commons 청크를 만듭니다.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
commons: {
name: 'commons',
chunks: 'initial',
minChunks: 2,
},
},
},
},
};
전체 애플리케이션에서 node_modules의 모든 코드를 포함하는 vendors 청크를 만듭니다.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
};
RegExp와 일치하는 특정 node_modules 패키지를 포함하는 custom vendor 청크를 만듭니다.
webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
name: 'vendor',
chunks: 'all',
},
},
},
},
};
This version of
stylelint-webpack-pluginonly works with webpack 5. For webpack 4, see the 2.x branch.
This plugin uses stylelint, which helps you avoid errors and enforce conventions in your styles.
To begin, you'll need to install stylelint-webpack-plugin:
npm install stylelint-webpack-plugin --save-dev
or
yarn add -D stylelint-webpack-plugin
or
pnpm add -D stylelint-webpack-plugin
[!NOTE]
You also need to install
stylelint >= 13from npm, if you haven't already:
npm install stylelint --save-dev
or
yarn add -D stylelint
or
pnpm add -D stylelint
[!NOTE]
If you are using Stylelint 13 rather than 14+, you might also need to install
@types/stylelintas a dev dependency if you encounter Stylelint-related type errors.
Then add the plugin to your webpack configuration. For example:
const StylelintPlugin = require("stylelint-webpack-plugin");
module.exports = {
// ...
plugins: [new StylelintPlugin(options)],
// ...
};
See stylelint's options for the complete list of available options . These options are passed directly to stylelint.
cachetype cache = boolean;
trueThe cache is enabled by default to decrease execution time.
cacheLocationtype cacheLocation = string;
node_modules/.cache/stylelint-webpack-plugin/.stylelintcacheSpecify the path to the cache location. This can be a file or a directory.
configFiletype context = string;
undefinedSpecify the config file location to be used by stylelint.
Note:
By default this is handled by
stylelint.
contexttype context = string;
compiler.contextA string indicating the root of your files.
excludetype exclude = string | string[];
['node_modules', compiler.options.output.path]Specify the files and/or directories to exclude. Must be relative to options.context.
extensionstype extensions = string | string[];
['css', 'scss', 'sass']Specify the extensions that should be checked.
filestype files = string | string[];
nullSpecify directories, files, or globs. Must be relative to options.context. Directories are traversed recursively, looking for files matching options.extensions. File and glob patterns ignore options.extensions.
fixtype fix = boolean;
falseIf true, stylelint will fix as many errors as possible. The fixes are made to the actual source files. All unfixed errors will be reported. See Autofixing errors docs.
formattertype formatter =
| string
| ((results: import("stylelint").LintResult[]) => string);
'string'Specify the formatter you would like to use to format your results. See the formatter option.
lintDirtyModulesOnlytype lintDirtyModulesOnly = boolean;
falseLint only changed files; skip linting on start.
stylelintPathtype stylelintPath = string;
stylelintPath to stylelint instance that will be used for linting.
threadstype threads = boolean | number;
falseSet to true for an auto-selected pool size based on number of CPUs. Set to a number greater than 1 to set an explicit pool size.
Set to false, 1, or less to disable and run only in main process.
By default, the plugin will automatically adjust error reporting depending on the number of Stylelint errors/warnings.
You can still force this behavior by using the emitError or emitWarning options:
emitErrortype emitError = boolean;
trueThe errors found will always be emitted. To disable, set to false.
emitWarningtype emitWarning = boolean;
trueThe warnings found will always be emitted. To disable, set to false.
failOnErrortype failOnError = boolean;
trueWill cause the module build to fail if there are any errors. To disable, set to false.
failOnWarningtype failOnWarning = boolean;
falseWill cause the module build to fail if there are any warnings, when set to true.
quiettype quiet = boolean;
falseWill process and report errors only, and ignore warnings, when set to true.
outputReporttype outputReport =
| boolean
| {
filePath?: string | undefined;
formatter?:
| (string | ((results: import("stylelint").LintResult[]) => string))
| undefined;
};
falseWrites the output of the errors to a file - for example, a json file for use for reporting.
The filePath is relative to the webpack config: output.path.
You can pass in a different formatter for the output file. If none is passed in the default/configured formatter will be used.
const outputReport = {
filePath: "path/to/file",
formatter: "json",
};
We welcome all contributions! If you're new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.
The svg-chunk-webpack-plugin creates optimized SVG sprites, according to Webpack's entrypoints. Each sprite contains only the SVG dependencies listed on its entrypoints to improved code splitting, even on SVG files.
The plugin includes the popular SVGO package to generates clean and optimized SVG sprites.
Code splitting is the key to deliver files without any content that is unused by the pages. It already exists for CSS, Javascript and now for SVG files with this plugin.
On multiple page application, each pages must includes only its necessary dependencies. In other words, it must include only the SVG files imported by its entrypoint and all its dependencies.
With reusable components, SVGs are often duplicated on all the project. Now, you can create a global SVG library and every Javascript files can easily import any SVG from this library. Entrypoint dependencies are automatically updated, thanks to the Webpack compilation.
When you work with SVGs exported by design softwares, like Sketch or Illustrator, their source code is never optimized and often contains comments, CSS classes which can create conflicts between them. The plugin automatically cleans all SVGs before creating the sprite.
The plugin works without configuration with already the optimized settings. For advanced usage, see the section using configuration.
The plugin is available as a package with the name of svg-chunk-webpack-plugin on npm and Github.
npm install svg-chunk-webpack-plugin --save-dev
yarn add svg-chunk-webpack-plugin --dev
[!WARNING] Plugin
svg-chunk-webpack-plugin@5is ESM only. [!NOTE] Minimum supportedNode.jsversion is16.20.0and Webpack>=5.10.3.
The project includes a minimalist example in the ./example directory. Run the npm run build:example command to execute the Webpack example and see the plugin's implementation in action.
The plugin will generate one SVG sprite for each entrypoints. Sprites are built in the output path directory with all the other assets. Each sprite filename is composed with its entrypoint name (in the example below, that would be home.svg).
First, let's add the loader and the plugin to the Webpack configuration.
[!WARNING] The loader and the plugin need to works together.
webpack.config.js
import SvgChunkWebpackPlugin from 'svg-chunk-webpack-plugin';
export default {
module: {
rules: [
{
test: /\.svg$/,
use: [
{
loader: SvgChunkWebpackPlugin.loader
}
]
}
]
},
plugins: [new SvgChunkWebpackPlugin()]
};
[!NOTE] For more flexibility and better performance, inline SVG files are better. Fewer HTTP requests, CSS properties to change the style, no flickering during the page load.
Then, include the sprite in the wanted pages (we use Twig in the following example).
home.html.twig
{{ include 'home.svg' }}
Finally, use the SVG with the <use> tag, like the following example. Replace <svg_name> by the SVG name (without the extension).
home.html.twig
<svg>
<use href="#<svg_name>"></use>
</svg>
The loader and the plugin accepts configuration to override the default behavior.
The loader configuration allow to personalize the SVGO configuration. SVGO optimization is executed during the loader process to optimize build performance.
configFileType:
type configFile = string | boolean;
Default: path.resolve(opts.root, 'svgo.config.js')
Tells the loader whether to load the custom SVGO configuration. Custom configuration can be disabled with configFile: false.
webpack.config.js
export default {
module: {
rules: [
{
test: /\.svg$/,
loader: SvgChunkWebpackPlugin.loader,
options: {
configFile: './path/svgo.config.js'
}
}
]
}
};
SVGO have a default preset to optimize SVG files. See how to configure svgo for details.
svgo.config.js
export default {
multipass: true,
plugins: [
{
name: 'preset-default',
params: {
overrides: {
inlineStyles: {
onlyMatchedOnce: false
},
removeViewBox: false
}
}
},
{
name: 'convertStyleToAttrs'
}
]
};
The plugin configuration allow to personalize sprite settings.
filenameType:
type filename = string;
Default: '[name].svg'
Tells the plugin whether to personalize the default sprite filename. The placeholder [name] is automatically replaced by entrypoints names.
webpack.config.js
export default {
plugins: [
new SvgChunkWebpackPlugin({
filename: '[name].svg'
})
]
};
[!NOTE] The
filenameparameter is compatible with Webpack caching placeholders, see the section caching.
svgstoreConfigType:
type svgstoreConfig = object;
Default: { cleanDefs: false, cleanSymbols: false, inline: true }
SVG sprites are built using the svgstore package. Update the parameters according to your needs from the options list available on the svgstore documentation.
webpack.config.js
export default {
plugins: [
new SvgChunkWebpackPlugin({
svgstoreConfig: {
svgAttrs: {
'aria-hidden': true,
style: 'position: absolute; width: 0; height: 0; overflow: hidden;'
}
}
})
]
};
[!NOTE] To avoid LinearGradient conflicts, avoid the
display: noneproperty which breaks SVG definitions.
generateSpritesManifestType:
type generateSpritesManifest = boolean;
Default: false
Tells the plugin whether to generate the sprites-manifest.json. The JSON file contains the list of all SVG included by entrypoints.
webpack.config.js
export default {
plugins: [
new SvgChunkWebpackPlugin({
generateSpritesManifest: true
})
]
};
generateSpritesPreviewType:
type generateSpritesPreview = boolean;
Default: false
Tells the plugin whether to generate the sprites-preview.html. The HTML preview contains a display list of all SVG included by entrypoints with the SVG overviews and the names. See the sprites preview of the example.
webpack.config.js
export default {
plugins: [
new SvgChunkWebpackPlugin({
generateSpritesPreview: true
})
]
};
With webpack caching, several placeholders are available depending on your needs. With SVG inlined in the page, this option is not useful.
[!NOTE] The
[contenthash]placeholder is the best option because it depends on the sprite content. Cache placeholders are expensive in build performance, use it only in production mode.
[contenthash]The [contenthash] placeholder will add a unique hash based on the content of the sprite. When the sprite's content changes, the hash will change as well.
webpack.config.js
export default {
plugins: [
new SvgChunkWebpackPlugin({
filename: '[name].[contenthash].svg'
})
]
};
[fullhash]The [fullhash] placeholder will add a unique hash generated for every build. When the compilation build is updated, the hash will change as well.
webpack.config.js
export default {
plugins: [
new SvgChunkWebpackPlugin({
filename: '[name].[fullhash].svg'
})
]
};
svg-chunk-webpack-plugin is licensed under the MIT License.
Created with ♥ by @yoriiis.
This plugin uses terser to minify/minimize your JavaScript.
Webpack v5 comes with the latest terser-webpack-plugin out of the box.
If you are using Webpack v5 or above and wish to customize the options, you will still need to install terser-webpack-plugin.
Using Webpack v4, you have to install terser-webpack-plugin v4.
To begin, you'll need to install terser-webpack-plugin:
npm install terser-webpack-plugin --save-dev
or
yarn add -D terser-webpack-plugin
or
pnpm add -D terser-webpack-plugin
Then add the plugin to your webpack configuration. For example:
webpack.config.js
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
};
Finally, run webpack using the method you normally use (e.g., via CLI or an npm script).
Works only with source-map, inline-source-map, hidden-source-map and nosources-source-map values for the devtool option.
Why?
eval wraps modules in eval("string") and the minimizer does not handle strings.cheap has no column information and the minimizer generates only a single line, which leaves only a single mapping.Using supported devtool values enable source map generation.
testType:
type test = string | RegExp | (string | RegExp)[];
Default: /\.m?js(\?.*)?$/i
Test to match files against.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
}),
],
},
};
includeType:
type include = string | RegExp | (string | RegExp)[];
Default: undefined
Files to include.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
include: /\/includes/,
}),
],
},
};
excludeType:
type exclude = string | RegExp | (string | RegExp)[];
Default: undefined
Files to exclude.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
exclude: /\/excludes/,
}),
],
},
};
parallelType:
type parallel = boolean | number;
Default: true
Use multi-process parallel running to improve the build speed.
Default number of concurrent runs: os.cpus().length - 1 or os.availableParallelism() - 1 (if this function is supported).
Note
Parallelization can speedup your build significantly and is therefore highly recommended.
Warning
If you use Circle CI or any other environment that doesn't provide the real available count of CPUs then you need to explicitly set up the number of CPUs to avoid
Error: Call retries were exceeded(see #143, #202).
booleanEnable/disable multi-process parallel running.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
};
numberEnable multi-process parallel running and set number of concurrent runs.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: 4,
}),
],
},
};
minifyType:
type minify = (
input: Record<string, string>,
sourceMap: import("@jridgewell/trace-mapping").SourceMapInput | undefined,
minifyOptions: {
module?: boolean | undefined;
ecma?: import("terser").ECMA | undefined;
},
extractComments:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
},
) => boolean)
| {
condition?:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
},
) => boolean)
| undefined;
filename?: string | ((fileData: any) => string) | undefined;
banner?:
| string
| boolean
| ((commentsFile: string) => string)
| undefined;
}
| undefined,
) => Promise<{
code: string;
map?: import("@jridgewell/trace-mapping").SourceMapInput | undefined;
errors?: (string | Error)[] | undefined;
warnings?: (string | Error)[] | undefined;
extractedComments?: string[] | undefined;
}>;
Default: TerserPlugin.terserMinify
Allows you to override the default minify function. By default plugin uses terser package. Useful for using and testing unpublished versions or forks.
Warning
Always use
requireinsideminifyfunction whenparalleloption enabled.
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 {
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,
}),
],
},
};
terserOptionsType:
interface terserOptions {
compress?: boolean | CompressOptions;
ecma?: ECMA;
enclose?: boolean | string;
ie8?: boolean;
keep_classnames?: boolean | RegExp;
keep_fnames?: boolean | RegExp;
mangle?: boolean | MangleOptions;
module?: boolean;
nameCache?: object;
format?: FormatOptions;
/** @deprecated */
output?: FormatOptions;
parse?: ParseOptions;
safari10?: boolean;
sourceMap?: boolean | SourceMapOptions;
toplevel?: boolean;
}
Default: default
Terser options.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
ecma: undefined,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
module: false,
// Deprecated
output: null,
format: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false,
},
}),
],
},
};
extractCommentsType:
type extractComments =
| boolean
| string
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
},
) => boolean)
| {
condition?:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
},
) => boolean)
| undefined;
filename?: string | ((fileData: any) => string) | undefined;
banner?:
| string
| boolean
| ((commentsFile: string) => string)
| undefined;
};
Default: true
Whether comments shall be extracted to a separate file, (see details).
By default, extract only comments using /^\**!|@preserve|@license|@cc_on/i RegExp condition and remove remaining comments.
If the original file is named foo.js, then the comments will be stored to foo.js.LICENSE.txt.
The terserOptions.format.comments option specifies whether the comment will be preserved - i.e., it is possible to preserve some comments (e.g. annotations) while extracting others, or even preserve comments that have already been extracted.
booleanEnable/disable extracting comments.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
}),
],
},
};
stringExtract all or some (use the /^\**!|@preserve|@license|@cc_on/i RegExp) comments.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: "all",
}),
],
},
};
RegExpAll comments that match the given expression will be extracted to a separate file.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: /@extract/i,
}),
],
},
};
functionAll comments that match the given expression will be extracted to a separate file.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: (astNode, comment) => {
if (/@extract/i.test(comment.value)) {
return true;
}
return false;
},
}),
],
},
};
objectAllows you to customize condition for extracting comments, and specify the extracted file name and banner.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: (fileData) =>
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
`${fileData.filename}.LICENSE.txt${fileData.query}`,
banner: (licenseFile) =>
`License information can be found in ${licenseFile}`,
},
}),
],
},
};
conditionType:
type condition =
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
},
) => boolean)
| undefined;
The condition that determines which comments should be extracted.
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"
`${fileData.filename}.LICENSE.txt${fileData.query}`,
banner: (licenseFile) =>
`License information can be found in ${licenseFile}`,
},
}),
],
},
};
filenameType:
type filename = string | ((fileData: any) => string) | undefined;
Default: [file].LICENSE.txt[query]
Available placeholders: [file], [query] and [filebase] ([base] for webpack 5).
The file where the extracted comments will be stored.
Default is to append the suffix .LICENSE.txt to the original filename.
Warning
We highly recommend using the
.txtextension. Using.js/.cjs/.mjsextensions may conflict with existing assets, which leads to broken code.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: "extracted-comments.js",
banner: (licenseFile) =>
`License information can be found in ${licenseFile}`,
},
}),
],
},
};
bannerType:
type banner = string | boolean | ((commentsFile: string) => string) | undefined;
Default: /*! For license information please see ${commentsFile} */
The banner text that points to the extracted file and will be added at the top of the original file.
It can be false (no banner), a String, or a function<(string) -> String> that will be called with the filename where the extracted comments have been stored.
The banner will be wrapped in a comment.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: true,
filename: (fileData) =>
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
`${fileData.filename}.LICENSE.txt${fileData.query}`,
banner: (commentsFile) =>
`My custom banner about license information ${commentsFile}`,
},
}),
],
},
};
Extract all legal comments (i.e. /^\**!|@preserve|@license|@cc_on/i) and preserve /@license/i comments.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: /@license/i,
},
},
extractComments: true,
}),
],
},
};
If you want to build without comments, use this config:
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: false,
},
},
extractComments: false,
}),
],
},
};
uglify-jsUglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
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: {},
}),
],
},
};
swcswc is a super-fast compiler written in Rust, producing widely supported JavaScript from modern standards and TypeScript.
Warning
The
extractCommentsoption is not supported, and all comments will be removed by default. This will be fixed in future
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: {},
}),
],
},
};
esbuildesbuild is an extremely fast JavaScript bundler and minifier.
Warning
The
extractCommentsoption is not supported, and all legal comments (i.e. copyright, licenses and etc) will be preserved.
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: {},
}),
],
},
};
Override the default minify function - use uglify-js for minification.
webpack.config.js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: (file, sourceMap) => {
// https://github.com/mishoo/UglifyJS2#minify-options
const uglifyJsOptions = {
/* your `uglify-js` package options */
};
if (sourceMap) {
uglifyJsOptions.sourceMap = {
content: sourceMap,
};
}
return require("uglify-js").minify(file, uglifyJsOptions);
},
}),
],
},
};
With default Terser minify function:
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: true,
},
}),
],
},
};
With built-in minify functions:
import { type JsMinifyOptions as SwcOptions } from "@swc/core";
import { type TransformOptions as EsbuildOptions } from "esbuild";
import { type MinifyOptions as TerserOptions } from "terser";
import { type MinifyOptions as UglifyJSOptions } from "uglify-js";
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
},
}),
],
},
};
We welcome all contributions! If you're new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.
다양한 유형의 가상 모듈을 생성할 수 있습니다. 예를 들어 .ts, .json, .css 등이 있으며, 기본값은 .js입니다.
const webpack = require('webpack');
new webpack.experiments.schemes.VirtualUrlPlugin({
myModule: `export const msg = "from virtual module"`,
});
src/app.js
import { msg } from 'virtual:myModule';
console.log(msg);
빌드 정보를 생성하는 가상 모듈을 만듭니다.
const webpack = require('webpack')
new webpack.experiments.schemes.VirtualUrlPlugin({
buildInfo: {
source: () {
return `export const buildTime = ${+new Date()}`
},
version: true
}
});
src/app.js
import { buildTime } from 'virtual:buildInfo';
console.log('App version: ', buildTime);
사용자 정의 스키마 사용
const webpack = require('webpack');
new webpack.experiments.schemes.VirtualUrlPlugin(
{
myModule: `export const msg = "from virtual module"`,
},
'v'
);
src/app.js
import { msg } from 'v:myModule';
console.log(msg);
다양한 유형의 가상 모듈을 여러 개 생성합니다.
const webpack = require('webpack');
new webpack.experiments.schemes.VirtualUrlPlugin({
myCssModule: {
type: '.css',
source: 'body{background-color: powderblue;}',
},
myJsonModule: {
type: '.json',
source: `{"name": "virtual-url-plugin"}`,
},
});
src/app.js
import json from 'virtual:myJsonModule';
import 'virtual:myCssModule';
라우팅 파일을 가상화합니다.
const webpack = require('webpack');
const path = require('path');
const watchDir = path.join(__dirname, './src/routes');
new webpack.experiments.schemes.VirtualUrlPlugin({
routes: {
source(loaderContext) {
// Use addContextDependency to monitor the addition or removal of subdirectories in watchDir to trigger the rebuilding of virtual modules.
loaderContext.addContextDependency(watchDir);
const files = fs.readdirSync(watchDir);
return `
export const routes = {
${files.map((key) => `${key.split('.')[0]}: () => import('./src/routes/${key}')`).join(',\n')}
}
`;
},
},
});
src/app.js
import { routes } from 'virtual:routes';
module.type (string): 가상 모듈의 콘텐츠 유형.module.source (string | ((loaderContext: import('webpack').LoaderContext<T>) => Promise<string> | string)): 가상 모듈의 콘텐츠를 생성하는 팩토리 함수.
module.version(boolean | string | () => string): 무효화가 발생하면 버전의 값이 이전과 다를 경우 소스 함수가 다시 호출됩니다. true로 설정하면 항상 트리거됩니다.
schema (string): 사용자 정의 가능한 가상 모듈 스키마, 기본값은 virtual입니다.
watch 모드인 경우, 제공된 경로나 정규 표현식에 해당되는 특정 파일을 무시합니다.
new webpack.WatchIgnorePlugin({ paths });
paths (Array<string | RegExp>): 무시해야 하는 디렉터리나 파일에 대한 정규 표현식 또는 절대 경로의 목록입니다.