前言
webpack
插件是 webpack
重要的组成部分,它是对 webapck
功能的一个扩展,并可以完成 loader
无法完成的工作。
plugin 和 loader 的区别
在刚学 webpack
的时候,我常常对 plugin 和 loader 傻傻分不清,经过一段时间的了解之后,发现两者是很好区分的(这个也是面试官很爱的考题哟)
- loader 是一个转译器,将 A 文件转译成 B 文件,比如将 A.less 转换成 B.css,是单纯的文件转换。
- plugin 是一个扩展器,它丰富了
webpack
本身,对于webapck
的每个阶段都可以进行插入,它是基于webpack
的事件机制,在webpack
某某些节点执行任务。
plugin 的用法
语法
plugins: [pluginA, pluginB, pluginC...]
数组中的插件是调用 new
方法得到的实例
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
介绍几个常用的 webpack
插件
imagemin-webpack-plugin
This is a simple plugin that uses Imagemin to compress all images in your project.
一个用于压缩图片的插件
安装
npm install imagemin-webpack-plugin
yarn add imagemin-webpack-plugin
配置
var ImageminPlugin = require('imagemin-webpack-plugin').default
// 如果是 es6:
// import ImageminPlugin from 'imagemin-webpack-plugin'
module.exports = {
plugins: [
// 请保证这个插件使用在其他可以插入的图片的插件之后
new ImageminPlugin({
disable: process.env.NODE_ENV !== 'production', // 在开发模式禁用
pngquant: {
quality: '95-100'
}
})
]
}
clean-webpack-plugin
A webpack plugin to remove/clean your build folder(s). 一个用于清理编译文件的插件
作用:在每次编译之前,清除上一次编译后产生的文件
安装
npm install --save-dev clean-webpack-plugin
yarn add --dev clean-webpack-plugin
配置
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpackConfig = {
plugins: [
new CleanWebpackPlugin(),
],
};
ProvidePlugin
懒人专用插件
自动加载模块,你只需要把常用的模块在插件中配置一次,在使用过程中就可以免去 import
或 require
安装
免安装,因为是 webpack
内置的插件
配置
const webpackConfig = {
plugins: [
new webpack.ProvidePlugin({
identifier: ['module1', 'property1'],
Vue: ['vue/dist/vue.esm.js', 'default'], // Vue
React: 'react', // react
$: 'jquery' // jquery
// ...
}),
],
};
purifycss-webpack
This plugin uses PurifyCSS to remove unused selectors from your CSS.
一个用于删除多余的 css 代码的插件,注意要搭配 extract-text-webpack-plugin
一起使用
安装
npm i -D purifycss-webpack purify-css
yarn add --dev purifycss-webpack purify-css
配置
const path = require('path');
const glob = require('glob');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const PurifyCSSPlugin = require('purifycss-webpack');
module.exports = {
entry: {...},
output: {...},
module: {
rules: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader',
loader: 'css-loader'
})
}
]
},
plugins: [
new ExtractTextPlugin('[name].[contenthash].css'),
// Make sure this is after ExtractTextPlugin!
new PurifyCSSPlugin({
// Give paths to parse for rules. These should be absolute!
paths: glob.sync(path.join(__dirname, 'app/*.html')),
})
]
};
自己写个组件
看了上面的几个组件,是不是也想试试自己写一个呢?
不过在编写 webpack
插件之前,需要有一定的 webpack
基础,如果对 webpack
还不熟悉的同学,可以看看我这两篇文章哟
在写插件之前,我们先了解一下,webpack
要求的写插件规范吧
一个官方的例子
const pluginName = 'ConsoleLogOnBuildWebpackPlugin';
class ConsoleLogOnBuildWebpackPlugin {
apply(compiler) {
compiler.hooks.run.tap(pluginName, compilation => {
console.log("webpack 构建过程开始!");
});
}
}
从例子中我们可以看到
- 需要一个
pluginName
插件名称 - 定义的插件是一个类
- 这个类里面要有一个
apply
方法,这个方法会被webapck
在编译过程中调用 - 通过给
hooks
定义处理函数,实现插件的功能
下面我们写一个可以打印出 webpack
重要的操作流程的插件
基础知识:webpack 的整体流程可以分为 env > init > compiler > make > seal > emit > done
- env 和 init 阶段负责初始化环境和激活
webpack
内部插件 - compiler 阶段是编译的开始
- make 阶段
webpack
会进行依赖分析和收集 - seal 阶段
webpack
会生成 chunk 文件 - emit 阶段
webpack
会把 chunks 写入硬盘 - done 阶段,顾名思义就会
webpack
工作完成啦
如果对上面的流程不熟悉的话,不妨看看我的两篇文章哟
操作流程打印插件
代码
const pluginName = 'ConsoleLogProgressPlugin';
class ConsoleLogProgressPlugin {
apply(compiler) {
console.log()
compiler.hooks.initialize.tap(pluginName, () => {
console.log('我发现 webpack 在准备环境')
});
compiler.hooks.compile.tap(pluginName, () => {
console.log('我发现 webpack 开始编译')
});
compiler.hooks.afterCompile.tap(pluginName, () => {
console.log('我发现 webpack 编译完成')
});
compiler.hooks.make.tap(pluginName, () => {
console.log('我发现 webpack 开始收集依赖')
});
compiler.hooks.finishMake.tap(pluginName, () => {
console.log('我发现 webpack 开始收集依赖完成')
});
compiler.hooks.compilation.tap(pluginName, (compilation) => {
compilation.hooks.seal.tap(pluginName, () => {
console.log('我发现 webpack 开始打包 chunk')
});
})
compiler.hooks.emit.tap(pluginName, () => {
console.log('我发现 webpack 发射文件')
});
compiler.hooks.done.tap(pluginName, () => {
console.log('我发现 webpack 搞定了')
});
}
}
module.exports = ConsoleLogProgressPlugin
配置
const ConsoleLogProgressPlugin = require('./plugin/ConsoleLogProgressPlugin')
module.exports = {
entry: './src/index.js',
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
}
],
},
plugins: [
new ConsoleLogProgressPlugin(),
],
};
效果
最后
总结一下:(引用了自己的前言)
webpack
插件是webpack
重要的组成部分,它是对webapck
功能的一个扩展,并可以完成loader
无法完成的工作。
感谢各位看官看到最后,码字不易,如果觉得这篇文章对你有用,请动动你们的小鼠标点个赞吧。
如果觉得写得不好的地方,也欢迎指出。