webpack4.0各个击破(7)—— plugin篇

简介: webpack作为前端最火的构建工具,是前端自动化工具链最重要的部分,使用门槛较高。本系列是笔者自己的学习记录,比较基础,希望通过问题 + 解决方式的模式,以前端构建中遇到的具体需求为出发点,学习webpack工具中相应的处理办法。

webpack作为前端最火的构建工具,是前端自动化工具链最重要的部分,使用门槛较高。本系列是笔者自己的学习记录,比较基础,希望通过问题 + 解决方式的模式,以前端构建中遇到的具体需求为出发点,学习webpack工具中相应的处理办法。(本篇中的参数配置及使用方式均基于webpack4.0版本

img_d6e7802c9640264835a13b85429f5a6a.png

img_60140e31006b5776c5560aeedc0c6988.png

一. plugin概述

1.1 Plugin的作用

plugin机制是webpack中另一个核心概念,它基于事件流框架tapable,你可以参考浏览器环境中的【DOM事件模型】【SPA模型中的生命周期钩子】或是node环境中的【EventEmitter模块】来理解其作用。plugin系统提供给开发者监听webpack生命周期并在特定事件触发时执行指定操作的能力。

当然,要写一个真正能实现一定功能的插件,你还需要了解CompilerCompilation这两个概念,网上可以找到非常多相关的文章(《webpack-docs/plugin》)。

1.2 Compiler

从表现上看,Compiler暴露了和webpack整个生命周期相关的钩子,通过如下的方式访问:

//基本写法
compiler.hooks.someHook.tap(...)
//如果希望在entry配置完毕后执行某个功能
compiler.hooks.entryOption.tap(...)
//如果希望在生成的资源输出到output指定目录之前执行某个功能
compiler.hooks.emit.tap(...)

webpack在重要的生命周期节点上都提供了事件钩子,我们可以借此加入一些自定义的功能。我们来编写一个插件,直观地看看webpack中涉及的钩子:

//check-compiler-hooks-plugin.js
const pluginName = 'checkCompilerHooksPlugin';
module.exports = class checkCompilerHooksPlugin {
    apply(compiler){
        //打印出entryOption执行完毕时Compiler暴露的钩子
        for(var hook of Object.keys(compiler.hooks)){
            console.log(hook);
        }
    }
}

可以看到Compiler上可以使用的钩子(当然这种方式看到的钩子和实际触发顺序无关):
img_2cc390d1ed942bce94aca73011596920.png

注意上图中Compiler.hooks暴露的事件钩子中有一个compilation,下一小节将解释它。

1.3 Compilation

Compilation暴露了与模块依赖有关的粒度更小的事件钩子,官方文档中的说法是模块会经历加载(loaded),封存(sealed),优化(optimized),分块(chunked),哈希(hashed)和重新创建(restored)这几个典型步骤,从上面的示例可以看到,compilationCompiler生命周期中的一个步骤,使用compilation相关钩子的通用写法为:

compiler.hooks.compilation.tap('SomePlugin',function(compilation, callback){
    compilation.hooks.someOtherHook.tap('SomeOtherPlugin',function(){
        ....
    })
});

我们仿照上面的方法就可以查看到compilation对象上(compilation事件触发时,在回调函数中取得的引用)暴露的事件钩子。

CompilerCompilation暴露的事件钩子总数超过30个,具体信息可以直接在官方文档直接查询API,在特定的阶段钩入想要添加的自定义功能。想要更好地理解plugin的作用机制,还需要了解webpack的整个生命周期以及事件流框架tapable.

二. 如何写一个plugin

根据webpack官方文档的说明,一个自定义的plugin需要包含:

  • 一个javascript命名函数
  • 插件函数的prototype上要有一个apply方法
  • 指定一个绑定到webpack自身的事件钩子
  • 注册一个回调函数来处理webpack实例中的指定数据
  • 处理完成后调用webpack提供的回调

官网给出了一个基本的结构示例:

//console-log-on-build-webpack-plugin.js
const pluginName = 'ConsoleLogOnBuildWebpackPlugin';
class ConsoleLogOnBuildWebpackPlugin {
    apply(compiler){
        compiler.hooks.run.tap(pluginName, compilation=>{
           console.log('webpack构建过程开始'); 
        });
    }
}

将其添加到webpack插件中后可以看到运行中触发了传入的回调函数:

img_8718818f8296bc093a97d3461fdbc937.png

四. 实战

《webpack4.0各个击破(4)——javascript & splitChunks》一文中,我们使用splitChunks功能对初始模块进行代码分割,在为多页面应用模型的html入口插入script标签时遇到了无法自动插入的问题,那么本节我们用一个webpack-dispatch-chunk-plugin来解决一下这个问题。

img_1a3eb42529c865f090d6c453a438f7d4.png

处理的逻辑就是利用html-webpack-plugin暴露的更改资源标签的事件钩子htmlWebpackPluginAlterAssetTags来进行资源处理,此时资源已经离过模块化和代码分割并已经在名称中加入了hash标记,只需要此时过滤掉名称中含有vendors且不包含相应入口名称的新的chunk即可,当然这只是一个基本功能,想要动态实现功能,还需要将上例中checkMap部分变为对Compiler或是Compilation上对应属性的引用,本篇不再赘述。

【参考】

[1] webpack之内部运行机制》

相关文章
|
JSON 前端开发 JavaScript
浅谈一下 webpack 以及 loader 和 plugin
浅谈一下 webpack 以及 loader 和 plugin
176 0
|
14天前
|
测试技术 开发者
如何确保 Webpack plugin 与其他插件的兼容性?
【10月更文挑战第23天】确保 Webpack plugin 与其他插件的兼容性需要从多个方面进行考虑和努力。通过遵循规范、进行充分测试、保持沟通协作等方式,
|
14天前
|
算法 测试技术 开发者
编写 Webpack plugin 时需要注意什么?
【10月更文挑战第23天】 编写 Webpack plugin 需要综合考虑多个方面的因素。只有在充分理解和掌握这些要点的基础上,才能编写出高质量、可靠且实用的 Plugin,为 Webpack 构建过程带来更多的价值和便利。
|
14天前
|
搜索推荐 测试技术 开发者
写一个 webpack plugin
【10月更文挑战第23天】编写一个 Webpack plugin 需要对 Webpack 的工作原理和机制有深入的了解,同时需要具备良好的编程能力和逻辑思维。通过合理设计和实现,Plugin 可以为我们的 Webpack 构建过程带来更多的灵活性和个性化。
|
26天前
|
前端开发 JavaScript
Webpack 常用 Loader 和 Plugin
【10月更文挑战第12天】Webpack 是一个强大的模块打包工具,能够将各种资源模块进行打包和处理。Loader 用于转换模块的源代码,如 `babel-loader` 将 ES6+ 代码转换为 ES5,`css-loader` 处理 CSS 文件等。Plugin 扩展 Webpack 功能,如 `HtmlWebpackPlugin` 自动生成 HTML 文件,`UglifyJsPlugin` 压缩 JavaScript 代码。通过合理配置和使用 Loader 和 Plugin,可以构建高效、优化的项目。
20 2
|
1月前
|
移动开发 JavaScript 前端开发
webpack学习四:使用webpack配置plugin,来使用HtmlWebpackPlugin、uglifyjs-webpack-plugin、webpack-dev-server等插件简化开发
这篇文章主要介绍了如何通过配置Webpack的插件,如HtmlWebpackPlugin、uglifyjs-webpack-plugin和webpack-dev-server,来简化前端开发流程。
33 0
webpack学习四:使用webpack配置plugin,来使用HtmlWebpackPlugin、uglifyjs-webpack-plugin、webpack-dev-server等插件简化开发
|
2月前
|
设计模式 前端开发 JavaScript
webpack实战之手写一个loader和plugin
该文章详细讲解了如何从零开始编写一个自定义的Webpack Loader和Plugin,包括它们的工作原理、开发步骤以及如何将自定义的Loader和Plugin集成到Webpack配置中。
webpack实战之手写一个loader和plugin
|
6月前
|
自然语言处理 JavaScript 前端开发
webpack实战——手写常用plugin
webpack实战——手写常用plugin
|
6月前
|
前端开发 JavaScript
Webpack中的Loader和Plugin:理解与使用
Webpack中的Loader和Plugin:理解与使用
|
6月前
|
前端开发 JavaScript
webpack 核心武器:loader 和 plugin 的使用指南(下)
webpack 核心武器:loader 和 plugin 的使用指南(下)
webpack 核心武器:loader 和 plugin 的使用指南(下)