webpack 提供了一个如何开发 webpack 插件的介绍,你可以直接访问这里查看,这里提供一个扩展 HtmlWebpackPlugin 的开发实例。

前面我们介绍过 HtmlWebpackPlugin, 这个插件允许将 webpack 动态打包的输出注入到页面中,但是,有的时候我们需要在这个页面中注入一些自定义的样式表或者脚本,HtmlWebpackPlugin 并不支持这个特性。有人向插件作者提了建议,这里是讨论的内容,结果是插件提供了几个事件来支持自己来实现这个特性。我们通过一个实例来演示如何使用这些事件来扩展 webpack。

需求

我们希望能够自动插入一个脚本的 script 在 webpack 生成的 script 之前,以便提前加载我们自定义的数据。最后生成的 HTML 类似这样的效果。

    <scripttype="text/javascript"src="./configuration/config.js"></script><scripttype="text/javascript"src="style.bundle.js"></script><scripttype="text/javascript"src="app.bundle.js"></script>

第一行是我们期望注入的脚本,其它两行是 webpack 导出的脚本。

插件入门

作为一个 webpack 的插件,使用方式是这样的。

plugins: [newMyPlugin({paths: ["./configuration/config.js"]}),newHtmlwebpackPlugin({title:'Hello Angular2!',template:'./src/index.html',inject:true})
],

所有的插件定义在 plugins 中,插件组成的一个数组,每个元素是一个插件的对象实例,具体传递什么参数,是你自己定义的。

从使用方式中可以看出,其实我们需要一个 JavsScript 的类函数,也就是说,写 webpack 插件就是定义一个这样的函数,这个函数需要接收参数。

webpack 还要求这个对象提供一个名为 apply 的函数,这个函数定义在插件的原型上,webpack 会调用插件实例的这个方法,在调用的时候还会传递一个参数,以便我们访问 webpack 的上下文信息。

官方提供的实例函数如下,最后一行是使用 CommonJs 风格导出这个插件。

functionHelloWorldPlugin(options) {//Setup the plugin instance with options...
}HelloWorldPlugin.prototype.apply= function(compiler) {compiler.plugin('done', function() {console.log('Hello World!'); });
};module.exports= HelloWorldPlugin;

传递参数

在我们的需求中,我们希望传递一个名为 paths 的路径参数,其中的每个路径需要生成一个 script 元素,插入到 webpack 导出的 script 之前。

newMyPlugin({paths: ["./configuration/config.js"]}),

在我们的插件中,需要保存这个参数,以便在 apply 函数中使用。

functionMyPlugin(options) {//Configure your plugin with options...
this.options =options;
}

直接保存到当前的对象实例中,在配合 new 的时候,this 就是刚刚创建的插件对象实例了。

实现

在 webpack 调用插件对象的 apply 方式的时候,我们首先应该获取我们保存的参数,使用 this 访问当前对象,获取刚刚保存的参数。

MyPlugin.prototype.apply = function(compiler) {//...var paths = this.options.paths;};

在我们的 apply 方法内,需要调用 compiler 的 plugin 函数。这个函数注册到 webpack 各个处理阶段上,可以支持的参数有:

<iframe id="iframe_0.730754913120701" style="border-style: none; width: 212px; height: 475px;" src="data:text/html;charset=utf8,%3Cstyle%3Ebody%7Bmargin:0;padding:0%7D%3C/style%3E%3Cimg%20id=%22img%22%20src=%22https://cloud.githubusercontent.com/assets/3348398/13768093/f46acd18-eaac-11e5-8895-a20a48e0972c.png?_=5649670%22%20style=%22border:none;max-width:1045px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.730754913120701',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no"></iframe>

我们这里使用了 compilation 编译任务。

MyPlugin.prototype.apply = function(compiler) {    var paths = this.options.paths;compiler.plugin('compilation', function(compilation, options) {});
};

webpack 会给我们提供的回调函数提供参数,我们可以注册编译阶段的事件了。html-webpack-plugin 提供了一系列事件。

Async:

  • html-webpack-plugin-before-html-generation
  • html-webpack-plugin-before-html-processing
  • html-webpack-plugin-alter-asset-tags
  • html-webpack-plugin-after-html-processing
  • html-webpack-plugin-after-emit

Sync:

  • html-webpack-plugin-alter-chunks

我们可以注册到它处理 HTML 之前,使用 html-webpack-plugin-before-html-processing 事件。

MyPlugin.prototype.apply = function(compiler) {    var paths = this.options.paths;compiler.plugin('compilation', function(compilation, options) {compilation.plugin('html-webpack-plugin-before-html-processing', function(htmlPluginData, callback) {......});});
};

在这个回调函数中,我们可以得到 html-webpack-plugin 提供的上下文对象,比如,它准备生成 script 所对应的 javascript 文件路径就保存在 htmlPluginData.assets.js 数组中,它会根据这个数组中的路径,依次生成 script 元素,然后插入到 Html 网页中。

我们需要的就是就我们的路径插入到这个数组的前面。

MyPlugin.prototype.apply = function(compiler) {    var paths = this.options.paths;compiler.plugin('compilation', function(compilation, options) {compilation.plugin('html-webpack-plugin-before-html-processing', function(htmlPluginData, callback) {            for (var i = paths.length - 1; i >= 0; i--) {htmlPluginData.assets.js.unshift(paths[i]);}callback(null, htmlPluginData);});});
};

完整的插件代码如下所示。

functionMyPlugin(options) {this.options =options;
}MyPlugin.prototype.apply= function(compiler) {    var paths = this.options.paths;compiler.plugin('compilation', function(compilation, options) {compilation.plugin('html-webpack-plugin-before-html-processing', function(htmlPluginData, callback) {            for (var i = paths.length - 1; i >= 0; i--) {htmlPluginData.assets.js.unshift(paths[i]);}callback(null, htmlPluginData);});});
};module.exports= MyPlugin;

最后一行是导出我们的插件。

讨论

通过 webpack 的插件机制,我们可以自由地扩展 webpack ,实现我们需要的特性。

See Also:

HOW TO WRITE A PLUGIN

如何写一个webpack插件(一)

webpack使用优化(基本篇) #2

html-res-webpack-plugin

转载于:https://www.cnblogs.com/mjian/p/9250095.html

扩展 HtmlwebpackPlugin 插入自定义的脚本相关推荐

  1. 使用 Microsoft Ajax Library 创建自定义客户端脚本

    MSDN地址:http://msdn.microsoft.com/zh-CN/library/bb386453.aspx Microsoft Ajax Library是微软提供的一套基于客户端的Aja ...

  2. 搜狗浏览器安装自定义JS脚本的方法~

                          搜狗浏览器安装自定义JS脚本的方法- 方法1 安装新搜狗浏览器右上常用工具栏,在"工具箱"上点击选"添加". 搜索安 ...

  3. 【键盘映射】AHK自定义Windows脚本

    AHK的使用 下载软件安装 // AHK软件下载地址 新建记事本编写代码后,改后缀为.ahk 放到开机自启动目录下 C:\ProgramData\Microsoft\Windows\Start Men ...

  4. dw重新定义html标记,扩展DW:自定义第三方标签解析

    扩展 Dreamweaver:自定义第三方标签的解析 因为最近一直在做 Dreamweaver 插件的开发,中文的资料非常少,自己英文又差,查看英文资料的时候不由头昏脑胀.迫不得已把其中一些重要的内容 ...

  5. 搜狗浏览器安装自定义JS脚本的方法

    方法1 安装新搜狗浏览器右上常用工具栏,在"工具箱"上点击选"添加". 搜索安装"Tampermonkey"应用(http://ie.sog ...

  6. 扩展clang 之 自定义 pragma 处理

    前言: 出于对程序性能影响的考虑,使用LLVM对代码进行混淆时,可能会有这么个需求:对特定的代码段进行混淆.比如在一 个函数内,希望对某一段核心代码进行混淆.这时,你就需要通过某种方式对这段核心代码进 ...

  7. postgresql中自定义函数脚本的备份及恢复

    [转自 housonglin1213 的博客]http://blog.csdn.net/housonglin1213/article/details/51005540 1.自定义函数脚本备份 CREA ...

  8. 往写好的html插入标签,写一个可插入自定义标签的 Textarea 组件

    - "插入自定义标签是什么鬼?" - "比如你要插入一个的标签..." - "什么情况下会有这种需求?" - "得罪了产品的情况下 ...

  9. mysql 存储过程 脚本_mysql利用存储过程插入大量数据脚本

    1.检查是否开启二进制日志 #查看是否开启二进制日志,ON表示开启,OFF表示没有开启 show variables like'log_bin_trust_function_creators'; #若 ...

最新文章

  1. 网络推广团队分享新手必看的长尾关键词挖掘技巧!
  2. java spring 拦截器_Spring MVC拦截器(Interceptor)的配置及使用
  3. 2019-03-13-算法-进化(验证回文串)
  4. python实现的、带GUI界面电影票房数据可视化程序
  5. mongodb备份每一天的数据
  6. 关于 Linux上面 安装nodejs ccap模块 实现图形验证码的一些事情
  7. php 添加数据sql语句,PHP添加/修改/删除SQL语句
  8. c语言空格eof什么意思,eof在c语言中表示什么?
  9. 关于Olly Dbg的使用报告
  10. iOS-百度地图之——POI检索失败BMK_SEARCH_PERMISSION_UNFINISHED
  11. Js打开QQ聊天对话窗口
  12. [转贴]民国记者有多牛:揭黑损人骂街是常事
  13. 调整分区后分区不见的数据找回法子
  14. 如何理解和成为测试工程师
  15. Office2019 Office2016 Office2010 Office365 系列各版本下载
  16. 强制关闭无法关闭的进程的方法
  17. 详解如何使用VS code搭建JavaScript环境(适合小白)
  18. 2020-12-04使用retrofit上传下载文件,监听下载进度
  19. 【自然语言处理】gensim的word2vec
  20. 网站开发进阶(五十)IE浏览器JS调试方法详解

热门文章

  1. Exception in thread “main“ org.apache.ibatis.binding.BindingException: Invalid bound statement (not
  2. 汇总二,js系列-css系列-其他综合系列
  3. Cadence内应该如何理解和使用balun做仿真。
  4. 【正点原子Linux连载】 第十九章 CAN Bus 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2
  5. 《道德经》第二十二章
  6. IMX8QX uuu烧录流程详解
  7. S5PV210开发板板载Gsensor KXTE9读取XYZ坐标值
  8. 磁卡感应卡二合一读写器|写卡器Z100-RF
  9. 什么你还不知道招聘信息,小唐来教你——最新2021爬取拉勾网招聘信息(二)
  10. 聚焦个性化与场景化,全新升级的三星电视看点何在?