深入webpack打包原理及loader和plugin的实现(5)

const path = require('path') const DemoWebpackPlugin = require('./plugins/demo-webpack-plugin') module.exports = { mode: 'development', entry: { main: 'https://www.jb51.net/article/src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, plugins: [ new DemoWebpackPlugin() ] }

再来看 demo-webpack-plugin.js 的实现

class DemoWebpackPlugin { constructor () { console.log('plugin init') } apply (compiler) { } } module.exports = DemoWebpackPlugin

我们在 DemoWebpackPlugin 的构造函数打印一条信息,当我们执行打包命令时,这条信息就会输出, plugin 类里面需要实现一个 apply 方法, webpack 打包时候,会调用 plugin 的 aplly 方法来执行 plugin 的逻辑,这个方法接受一个 compiler 作为参数,这个 compiler 是 webpack 实例

plugin的核心在于,apply方法执行时,可以操作webpack本次打包的各个时间节点(hooks,也就是生命周期勾子),在不同的时间节点做一些操作

关于webpack编译过程的各个生命周期勾子,可以参考 Compiler Hooks

同样,这些hooks也有同步和异步之分,下面演示 compiler hooks 的写法,一些重点内容可以参考注释:

class DemoWebpackPlugin { constructor () { console.log('plugin init') } // compiler是webpack实例 apply (compiler) { // 一个新的编译(compilation)创建之后(同步) // compilation代表每一次执行打包,独立的编译 compiler.hooks.compile.tap('DemoWebpackPlugin', compilation => { console.log(compilation) }) // 生成资源到 output 目录之前(异步) compiler.hooks.emit.tapAsync('DemoWebpackPlugin', (compilation, fn) => { console.log(compilation) compilation.assets['index.md'] = { // 文件内容 source: function () { return 'this is a demo for plugin' }, // 文件尺寸 size: function () { return 25 } } fn() }) } } module.exports = DemoWebpackPlugin

我们的这个 plugin 的作用就是,打包时候自动生成一个 md 文档,文档内容是很简单的一句话

上述异步hooks的写法也可以是以下两种:

// 第二种写法(promise) compiler.hooks.emit.tapPromise('DemoWebpackPlugin', (compilation) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve() }, 1000) }).then(() => { console.log(compilation.assets) compilation.assets['index.md'] = { // 文件内容 source: function () { return 'this is a demo for plugin' }, // 文件尺寸 size: function () { return 25 } } }) }) // 第三种写法(async await) compiler.hooks.emit.tapPromise('DemoWebpackPlugin', async (compilation) => { await new Promise((resolve, reject) => { setTimeout(() => { resolve() }, 1000) }) console.log(compilation.assets) compilation.assets['index.md'] = { // 文件内容 source: function () { return 'this is a demo for plugin' }, // 文件尺寸 size: function () { return 25 } } })

最终的输出结果都是一样的,在每次打包时候生成一个md文档

深入webpack打包原理及loader和plugin的实现

到此为止,本文介绍了webpack打包的基本原理,以及自己实现loader和plugin的方法。希望本文内容能对大家对webpack的学习,使用带来帮助。更多相关webpack打包loader和plugin内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/206cf6e003a80567f228417a7509ef79.html