持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
自定义plugin的实现
插件就是在某个时刻,帮助我们完善一些工作的机制。它的复杂程度比loader高,场景比loader广,因为他作用于整个webpack打包生命周期的。webpack打包编译过程中,会触发一系列的钩子事件(插件)
插件基本结构
// 插件的结构 类
// 必须要用apply函数
class TxtWebpackPlugin {
constructor(options) {
console.log(options);
}
// 提供当前打包的compiler对象,可以拿到钩子,注册事件
apply(compiler) {
// compiler.hooks
compiler.hooks.emit.tapAsync("TxtWebpackPlugin", (compilation, cb) => {
// console.log(compilation.assets)
// 往资源模块中添加一个资源
// emit AsyncSeriesHook 在⽣成⽂件到output⽬录之前执⾏,回调参数:compilation
const content = `这是一个测试的资源模块`
compilation.assets["frllk.txt"] = {
source: function () {
return content
},
size: function () {
return content.length // 打包信息栏的显示信息,并不影响文件的真实体积,需要保持文档的准确性
}
}
cb()
})
}
}
module.exports = TxtWebpackPlugin
基本流程
Webpack 的基本流程可以分为 3 个阶段:
- 准备阶段:主要任务是创建
Compiler和Compilation对象; - 编译阶段:这个阶段任务是完成 modules 解析,并且⽣成 chunks;
- module 解析:包含了三个主要步骤,创建实例、 loaders 应⽤和依赖收集;
- chunks ⽣成,主要步骤是找到每个
chunk所需要包含的modules。 - 产出阶段:这个阶段的主要任务是根据
chunks⽣成最终⽂件,主要有三个步骤:模板 Hash 更新,模板渲染 chunk,⽣成⽂件。
Compiler
Compiler 模块是 Webpack 最核⼼的模块。每次执⾏ Webpack 构建的时候,在 Webpack 内部,会⾸
先实例化⼀个 Compiler 对象,然后调⽤它的 run ⽅法来开始⼀次完整的编译过程。我们直接使⽤
Webpack API webpack(options) 的⽅式得到的就是⼀个 Compiler 实例化的对象,这时候 Webpack
并不会⽴即开始构建,需要我们⼿动执⾏ comipler.run() 才可以。
Compiler 钩⼦
可以通过下⾯的代码,获取了对应的钩⼦名称:
const webpack = require("webpack") // 引入webpack
const config = require("./webpack.config") // 引入webpack打包配置
const compiler = webpack(config) // 执行webpack,把配置传进去,生成一个对象compiler,里面记录了本次打包的所有信息
// compiler.hooks()
Object.keys(compiler.hooks).forEach(hookName => {
// 同步钩子 用tap
// 异步钩子 用tapAsync
compiler.hooks[hookName].tap("事件名称", () => {
console.log('%c%s', 'color: red; background: yellow; font-size: 16px;', 'run---------->', hookName)
})
})
compiler.run() // 入口函数
得到 compiler.run() 之后的⼯作流程: