webpack插件构成部分

  • 一个具名javascript函数
  • 在他的原型上定义apply方法
  • 指定一个触及到 webpack本身的事件钩子
  • 操作webpack内部的特定实例数据
  • 实现功能后调用 webpack提供的callback函数

webpack基本架构

插件有一个构造函数实例化出来, 构造函数定义apply方法,在安装插件时,apply方法会被webpack的compiler调用一次。apply方法可以接受一个webpack的compiler对象的引用, 从而可以在回调函数中访问到compiler对象。

插件钩子和触发方法简介

Webpack 提供钩子有很多,这里简单介绍几个

  • entryOption:在 webpack 选项中的 entry 配置项 处理过之后。
  • afterPlugins : 设置完初始插件之后。
  • compilation : 编译创建之后,生成文件之前。
  • emit : 生成资源到 output 目录之前。
  • done : 编译完成。

Webpack 提供三种触发钩子的方法:

  • tap :以同步方式触发钩子(支持两个参数,插件名称compilation 和回调函数callback)
  • tapAsync :以异步方式触发钩子;
  • tapPromise :以异步方式触发钩子,返回 Promise;\

官网提供简单的插件结构

class HelloWorldPlugin {apply(compiler) {compiler.hooks.done.tap('Hello World Plugin', (stats /* 在 hook 被触及时,会将 stats 作为参数传入。 */) => {console.log('Hello World!');});}
}
module.exports = HelloWorldPlugin;

使用插件

// webpack.config.js
var HelloWorldPlugin = require('hello-world');module.exports = {// ... 这里是其他配置 ...plugins: [new HelloWorldPlugin({ options: true })]
};

自定义实现插件需求:动态添加script标签

我们先在模版中做个标记,后面进行标记替换

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Webpack 插件开发入门</title>
</head>
<body><!-- other code --><!--SetScriptTimestampPlugin inset script-->
</body>
</html>

我们插件应该是要在 HTML 输出之前,动态添加 script 标签,所以我们选择钩子是 compilation 阶段

compilation 继承于compiler,包含 compiler 所有内容(也有 Webpack 的 options),而且也有 plugin 函数接入任务点。

class SetScriptTimestampPlugin {apply(compiler) {compiler.hooks.compilation.tap('SetScriptTimestampPlugin', (compilation, callback) => {// 插件逻辑 调用compilation提供的plugin方法compilation.plugin("html-webpack-plugin-before-html-processing",function(htmlPluginData, callback) {// 读取并修改 script 上 src 列表let jsScr = htmlPluginData.assets.js[0];htmlPluginData.assets.js = [];let result = `<script>let scriptDOM = document.createElement("script");let jsScr = "./${jsScr}";scriptDOM.src = jsScr + "?" + new Date().getTime();document.body.appendChild(scriptDOM)</script>`;let resultHTML = htmlPluginData.html.replace("<!--SetScriptTimestampPlugin inset script-->", result);// 返回修改后的结果htmlPluginData.html = resultHTML;});});}
}
module.exports = SetScriptTimestampPlugin;

在上面插件逻辑中,具体做了这些事

1. 执行 compilation.plugin  方法,并传入两个参数:插件事件和回调方法

  • 所谓“插件事件”即插件所提供的一些事件,用于监听插件状态

2.获取脚本文件名称列表并清空 

  • 在回调方法中,通过 htmlPluginData.assets.js 获取需要通过 script 引入的脚本文件名称列表,拷贝一份,并清空原有列表

3.编写替换逻辑

  • 动态创建一个 script 标签,将其 src 值设置为上一步读取到的脚本文件名,并在后面拼接 时间戳 作为参数。

4.插入替换逻辑

  • 通过 htmlPluginData.html 可以获取到模版文件的字符串输出,我们只需要将模版字符串中替换入口 <!--SetScriptTimestampPlugin inset script--> 替换成我们上一步编写的替换逻辑即可。

5.返回HTML文件

  • 最后将修改后的 HTML 字符串,赋值给原来的 htmlPluginData.html 达到修改效果

最后使用插件

// webpack.config.jsconst SetScriptTimestampPlugin = require("./SetScriptTimestampPlugin.js");
module.exports = {// ... 省略其他配置plugins: [// ... 省略其他插件new SetScriptTimestampPlugin()  ]
}

        

自定义实现webpack插件原理解析相关推荐

  1. MyBatis插件原理解析及自定义插件实践

    一.插件原理解析 首先,要搞清楚插件的作用.不管是我们自定义插件,还是用其他人开发好的第三方插件,插件都是对MyBatis的四大核心组件:Executor,StatementHandler,Param ...

  2. android黑科技系列——微信抢红包插件原理解析和开发实现

    一.前言 自从几年前微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...

  3. Webpack HMR 原理解析

    Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送 ...

  4. “约见”面试官系列之常见面试题第四十四篇之webpack打包原理解析?(建议收藏)

    webpack打包是如何运行的 也可以称为,webpack是如何实现模块化的 CommonJS是同步加载模块,一般用于node.因为node应用程序运行在服务器上,程序通过文件系统可以直接读取到各个模 ...

  5. http-invoker插件原理解析

    背景 项目中不可避免的使用第三方api接口,但是如果使用apache-httpclient总是不可避免需要设置连接池等,即使每次拷贝对于项目来说也显得冗余 http-api-invoker的方式可以使 ...

  6. 真香定律!Android动态换肤实现原理解析,原理+实战+视频+源码

    自己项目中一直都是用的开源的xUtils框架,包括BitmapUtils.DbUtils.ViewUtils和HttpUtils四大模块,这四大模块都是项目中比较常用的.最近决定研究一下xUtils的 ...

  7. 霖呆呆的六个自定义Webpack插件详解-自定义plugin篇(3)

    霖呆呆的webpack之路-自定义plugin篇 你盼世界,我盼望你无bug.Hello 大家好!我是霖呆呆! 有很多小伙伴在打算学写一个webpack插件的时候,就被官网上那一长条一长条的API给吓 ...

  8. webpack原理解析【万字长文】

    开场白 大家好,我是Webpack,AKA打包老炮,我的slogan是:"打天下的包,让Rollup无包可打". 今天我要带来的才艺是:剖析打包的艺术  故事还要从一次npm包工头 ...

  9. Android 插件化原理解析——插件加载机制

    上文 Activity生命周期管理 中我们地完成了『启动没有在AndroidManifest.xml中显式声明的Activity』的任务:通过Hook AMS和拦截ActivityThread中H类对 ...

最新文章

  1. 百万级访问量网站的技术准备工作[转帖]
  2. 在C#里怎样获得当前Windows操作系统的语言种类?以及如何知道当前Windows版本?...
  3. modelandview 可以返回html么_Python: 爬虫网页解析工具lxml.html(一)
  4. 常见排序算法(C实现)
  5. 各个线程顺序循环执行
  6. linux mount 原文件夹,window文件夹mount挂载Linux
  7. VIP客户服务系统设计(四)——按用户角色构思系统功能(上)
  8. android应用程序列表,List列表应用程序-小知识 #103
  9. JavaScript 凭什么力压 Java、Python 横扫编程语言榜单?
  10. catkin_make和cmake
  11. python中requests模块使用
  12. silverlight:手写板/涂鸦/墨迹/InkPresenter示例程序
  13. matlab常用插值函数
  14. 利用接口和继承实现  求三角形 圆形面积 和以圆形为底的圆锥形的体积
  15. 转:稻盛和夫:在软弱的领导人手下工作,是可悲的
  16. 关于数字的智力题-三个女儿的年龄
  17. WORDBOOK - ForeverStrong Cheng - YongQiang Cheng
  18. 信息安全-网站安全需求分析与安全保护工程(一)
  19. mysql 查看等待事件_分享两个实用SQL--查看故障时间等待事件、问题sql及会话访问次数...
  20. 【ZZULIOJ】1107: 回文数猜想(函数专题)

热门文章

  1. 传统餐桌行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  2. 蓝桥杯12题c语言,2012.C语言‘蓝桥杯“预赛.真题.高职
  3. 数字电子技术基础大作业---电子表、流水灯
  4. 代表 YGG 的 Illuvium 首席游戏大使 —— Zom
  5. 频率选择性衰落、时间选择性衰落
  6. 前端安全系列:如何防止CSRF攻击?
  7. 前端开发工具HbuilderX的使用技巧
  8. 厦大2021届大一小学期C语言作业1 数组+字符串+指针+位操作
  9. git 分支教程小游戏
  10. 养猫日记-20200411