前面讲了:
本篇文章讲解 常用 plugins 及配置。 为什么要配置plugins,因为webpack 只能识别js,json 文件,无法识别 .css 等其他文件,因此需要各种loader 处理对应格式文件。
一:html-webpack-plugin (HtmlWebpackPlugin)
css
这个很熟悉了,前面用过了,它支持打包时,自动生成html文件或者按模板配置生成html文件,并且会按需自动插入打包好的静态文件自动插入html中。
js
npm i html-webpack-plugin --D
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './assets/index.html'), // 自定义模板
inject: 'body', // 插入到body
}),
二:clean-webpack-plugin (CleanWebpackPlugin)
这个前面也用过了,我们练习的过程中,每次修改了一些配置,重新打包时,都需要手动删除dist文件夹这个操作可以借助于一个插件来帮助我们自动完成。
js
# 安装
$ npm i clean-webpack-plugin -D
// 配置 部分
/*
1. 绝大部分plugin导出都是使用默认导出,但是CleanWebpackPlugin使用的是普通导出,所以在引入的时候需要注意
2. 多少情况下,plugin是一个个的类,所以导入的名称首字母是大写的,且使用的时候使用new来创建对应的实例对象
*/
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// ...... 此处为省略的其它配置
module.exports = {
plugins: [
new CleanWebpackPlugin()
]
}
三: DefinePlugin
scss
Webpack5自带plugin(不需要单独安装),我们可以通过 `DefinePlugin` 可以定义一些全局的变量,我们可以在模块当中直接使用这些变量,会在编译阶段,将你代码中的变量替换为对应的值。
js
// 配置 --- 部分
const { DefinePlugin } = require('webpack')
// ...
plugins: [
new DefinePlugin({
// DefinePlugin中配置的key-value的值会做作为字符串进行解析,所以其值需要被设置成字符串类型
// 注意,其取值的时候,会将引号中的内容单独取出,作为值来使用 (比较特别)
// 所以'./'会被看成是./ 所以会报错,因此需要写成"'./'"
BASE_URL: "'./'",
// 配置在DefinePlugin中的key,可以在任何地方被引用,包括vue文件,js文件
// webpack在编译的时候会对这些变量进行统一的解析和处理
ENV: JSON.stringify('development')
})
]
go
此時我们就可以在全局,也就是任何地方,使用我们在`DefinePlugin`中定义的全局变量
例如,在index.html模板中
html
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
js
if (ENV === 'development') {
// 开发环境适用的代码
} else {
// 生产环境适用的代码
}
四:copy-webpack-plugin
如果我们将一些文件放到public的目录下,需要在编译的时候,将这个目录会被复制到dist文件夹下 这个复制的功能,我们可以使用CopyWebpackPlugin来完成
js
# 安装
$ npm install copy-webpack-plugin -D
js
const CopyPlugin = require("copy-webpack-plugin");
plugins: [
new CopyPlugin({
patterns: [
// copy assets/favicon.ico 文件到 {output} 路径下
{ context: './assets', from: 'favicon.ico', to: '', info: { minimized: true } },
// copy assets/js/a.js 文件到 {output}/js 路径下,并且会在production下进行压缩
{ context: './assets/js', from: 'a.js', to: 'js' },
// copy assets/lib/ 路径下所有文件到 {output}/3rd 路径下,并且不压缩
{ context: './assets/lib', from: '**', to: '3rd', info: { minimized: true } },
],
}),
五: SplitChunksPlugin
Webpack5自带plugin,用于按需对打包文件进行拆分chunks。 Webpack内有默认配置,chunks
默认是 async
,所以在如果不配置默认情况下,如果用了异步引用(比如动态import)则会进行拆分;如果有别的情况需求,可以按文档设置。
如果没有特别拆分包需求,可以按下面配置,把 node_modules
包单拆出来。
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,
},
},
},
},
};
六: mini-css-extract-plugin
这个插件可以将将 CSS
提取到单独的文件中。并且支持按需加载 CSS
和 SourceMaps
。
js
npm i mini-css-extract-plugin --D
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
rules: [
{
// less/css
test: /\.(less|css)$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
},
{
// sass/scss/css
test: /\.(sa|sc|c)ss$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[contenthash:8].css",
chunkFilename: "[id].[contenthash:8].css",
ignoreOrder: true,
}),
],
七: css-minimizer-webpack-plugin
用来压缩css文件,需要配合 mini-css-extract-plugin
使用。
js
npm i css-minimizer-webpack-plugin --D
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
optimization: {
minimize: devMode ? false : true,
minimizer: [
new CssMinimizerPlugin({}),
],
八: webpack-bundle-analyzer
很常用的Webpack打包分析插件,使用交互式可缩放树形地图可视化,并输出文件的大小。可以方便开发人员检查打包后的文件拆分、分析文件大小等。
在缩减打包文件、按需加载拆分打包文件、提高首屏加载效率时会很有用。
js
npm i webpack-bundle-analyzer -D
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
plugins: [
new BundleAnalyzerPlugin(),
],
九: webpack-deadcode-plugin
该插件会检查项目中没有引用到的文件,以及没有引用到的exports,方便开发维护。
js
npm i webpack-deadcode-plugin -D
const DeadCodePlugin = require('webpack-deadcode-plugin');
optimization: {
usedExports: true, // 如果想扫描 unused exports,需要设置为true,production下默认是true
},
plugins: [
new DeadCodePlugin({
patterns: [
'./src/**', // 只扫描src路径下所有文件
],
exclude: [
'./**/mapping.xml',
'./**/*.md',
],
log: "none", // 不输出log
exportJSON: `./analysis` // 结果生成到analysis路径下
})
],
参考: