插件和loader
开发loader插件之前有说过,loader一般是用于编译等预处理任务操作,而插件主要用于功能的扩展,总的来说,功能应该更强大一些。
和开发loader不同的是,loader-runner提供了loader的上下文,开发更方便,而开发webpack没有这样的独立环境,我们得在正式的webpack配置环境中测试验证。
插件基本结构
插件主要包括以下5个部分:
// 1、插件名称
class MyPlugin {
constructor (options) {
this.options = options
},
// 2、apply方法
apply (compiler) {
// 3、插件的hooks
compiler.hooks.done.tap('My Plugin', (stats) => {
// 4、逻辑处理
console.log('Hello, My Plugin')
})
}
}
module.exports = MyPlugin // 5、导出插件
使用插件:
module.exports = {
plugins: [new MyPlugin()]
}
插件运行环境
新建配置文件,在配置文件plugins中引入调试的插件:
const path = require('path')
const MyPlugin = require('../plugin/my-plugin.js')
module.exports = {
entry: {
lib: path.join(__dirname, 'app.js')
},
output: {
path: path.join(__dirname, 'build'),
filename: '[name].js'
},
plugins: [new MyPlugin()]
}
错误处理
插件是一个类,在构造函数中可获取配置传入的入参,如果需要校验参数的类型或其他逻辑,可直接通过throw抛出错误:
throw new Error('error...')
而一般在功能开发过程中需要报错或者警告,可通过compilation来完成。
compiler模块是webpack的主要引擎,它通过CLI或者Node API传递的所有选项创建出一个compilation实例。
...
compiler.hooks.run.tap('myPlugin', (compilation) => {
compilation.warning.push('warning') // 警告
compilation.error.push('error') // 错误
})
...
compiler常用钩子函数
run
在开始读取records之前调用,回调参数compiler。
records指的是存储有跨多次构建的模块标识符的数据片段。可以通过这个文件来记录每次构建间的模块变化。
compile
beforeCompile之后立即调用。但在新的compilation创建之前,这个钩子不会被复制到子编译器。回调参数compilationParams。
compilation
compilation创建之后执行。回调参数compilation和compilationParams。
done
在compilation完成时执行。这个钩子不会被复制到子编译器。回调参数是stats。
stats是在构建过程中记录的一些警告、报错、webpack版本等信息。