说说webpack中常见的Plugin?解决了什么问题?
是什么
Plugin(Plug-in)是一种计算机应用程序, 它和主应用程序互相交互, 以提供特定的功能
是一种遵循一定规范的应用程序接口编写出来的程序, 只能运行在程序规定的系统下, 因为其需要调用原纯净系统提供的函数库或者数据
webpack中的plugin也是如此, plugin赋予其各种灵活的功能, 例如打包优化、资源管理、环境变量注入等, 它们会运行在webpack的不同阶段(钩子 / 生命周期), 贯穿了webpack整个编译周期

目的在于解决loader无法实现的其他事
配置方式
这里讲述文件的配置方式, 一般情况, 通过配置文件导出对象中plugins属性传入new实例对象。如下所示:
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('kevin-notebook-next.github.io/src/pages/interview/webpack/webpack.mdx'); // 访问内置的插件
module.exports = {
...
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({ template: './src/index.html' }),
],
};特性
其本质是一个具有apply方法javascript对象
apply方法会被webpack compiler调用, 并且在整个编译生命周期都可以访问compiler对象
const pluginName = 'ConsoleLogOnBuildWebpackPlugin';
class ConsoleLogOnBuildWebpackPlugin {
apply(compiler) {
compiler.hooks.run.tap(pluginName, (compilation) => {
console.log('webpack 构建过程开始!');
});
}
}
module.exports = ConsoleLogOnBuildWebpackPlugin;compiler hook的tap方法的第一个参数, 应是驼峰式命名的插件名称
关于整个编译生命周期钩子, 有如下:
entry-option: 初始化 optionruncompile: 真正开始的编译, 在创建 compilation 对象之前compilation: 生成好了 compilation 对象make从entry开始递归分析依赖, 准备对每个模块进行 buildafter-compile: 编译 build 过程结束emit: 在将内存中 assets 内容写到磁盘文件夹之前after-emit: 在将内存中 assets 内容写到磁盘文件夹之后done: 完成所有的编译过程failed: 编译失败的时候
常见的Plugin
-AggressiveSplittingPlugin: 将原来的chunk分为更小的chunk
-BabelMinifyWebpackPlugin: 使用babel-minify进行压缩
-BannerPlugin: 在每个生成的chunk顶部添加banner
-CommonsChunkPlugin: 提取chunks之间共享的通用模块
-CompressionWebpackPlugin: 预先准备的资源压缩版本, 使用Content-Encoding提供访问服务
-ContextReplacementPlugin: 重写require表达式的推断上下文
-CopyWebpackPlugin: 将单个文件或整个目录复制到构建目录
-DefinePlugin: 允许在编译时(compile time)配置的全局常量
-DllPlugin: 为了极大减少构建时间, 进行分离打包
-EnvironmentPlugin:DefinePlugin中 process.env 键的简写方式
-ExtractTextWebpackPlugin: 从bundle中提取文本(css)到单独的文件
-HotModuleReplacementPlugin: 启用模块热替换
-HtmlWebpackPlugin: 简单创建HTML文件, 用于服务器访问
-I18nWebpackPlugin: 为bundle增加国际化支持
-IgnorePlugin: 从bundle中排除某些模块
-LimitChunkCountPlugin: 设置chunk的最小/最大限制, 已微调和控制chunk
-LoaderOptionsPlugin: 用于webpack 1迁移到webpack 2
-MinChunkSizePlugin: 确保chunk大小超过指定限制
-NoEmitOnErrorsPlugin: 在输出阶段时, 遇到编译错误跳过
-NormalModuleReplacementPlugin: 替换与正则表达式匹配的资源
下面介绍几个常用的插件用法:
HtmlWebpackPlugin
在打包结束后, ⾃动生成⼀个html⽂文件, 并把打包生成的js模块引⼊到该html中
npm install --save-dev html-webpack-plugin// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
...,
plugins: [
new HtmlWebpackPlugin({
title: "My App",
filename: "app.html",
template: "./src/html/index.html"
})
]
};<!--./src/html/index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title><%=htmlWebpackPlugin.options.title%></title>
</head>
<body>
<h1>html-webpack-plugin</h1>
</body>
</html>在html模板中, 可以通过<%=htmlWebpackPlugin.options.XXX%>的方式获取配置的值
更多的配置可以自寻查找
clean-webpack-plugin
删除(清理)构建目录
npm install --save-dev clean-webpack-pluginconst {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
...,
plugins: [
...,
new CleanWebpackPlugin(),
...
]
}mini-css-extract-plugin
提取CSS到一个单独的文件中
npm install --save-dev mini-css-extract-pluginconst MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
...,
module: {
rules: [
{
test: /\.s[ac]ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
'css-loader',
'sass-loader'
]
}
]
},
plugins: [
...,
new MiniCssExtractPlugin({
filename: '[name].css'
}),
...
]
}DefinePlugin
允许在编译时创建配置的全局对象, 是一个webpack内置的插件, 不需要安装
const { DefinePlugun } = require('webpack')
module.exports = {
...
plugins:[
new DefinePlugin({
BASE_URL: '"./"'
})
]
}这时候编译template模块的时候, 就能通过下述形式获取全局对象
<link rel="icon" href="<%= BASE_URL%>favicon.ico" />copy-webpack-plugin
复制文件或目录到执行区域, 如vue的打包过程中, 如果我们将一些文件放到public的目录下, 那么这个目录会被复制到dist文件夹中
npm install copy-webpack-plugin -Dmodule.exports = {
...,
plugins: [
new CopyWebpackPlugin({
parrerns:[
{
from:"public",
globOptions:{
ignore:[
'**/index.html'
]
}
}
]
})
]
}复制的规则在patterns属性中设置:
- from: 设置从哪一个源中开始复制
- to: 复制到的位置, 可以省略, 会默认复制到打包的目录下
- globOptions: 设置一些额外的选项, 其中可以编写需要忽略的文件