`

扩展 HtmlwebpackPlugin 插入自定义的脚本

 
阅读更多

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

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

需求

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

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

 

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

插件入门

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

复制代码
plugins: [
    new MyPlugin({
        paths: ["./configuration/config.js"]
    }),
    new HtmlwebpackPlugin({
        title: 'Hello Angular2!',
        template: './src/index.html',
        inject: true
    })
],
复制代码

 

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

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

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

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

复制代码
function HelloWorldPlugin(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 之前。

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

 

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

function MyPlugin(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);
        });
    });
};
复制代码

 

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

复制代码
function MyPlugin(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

 

分享到:
评论

相关推荐

    前端开源库-html-webpack-filter-extend-plugin

    而html-webpack-filter-extend-plugin则是在此基础上进行增强,提供了更强大的过滤和扩展能力,使开发者能够自定义HTML生成过程,比如动态添加脚本、样式链接或者修改HTML内容。 这个插件的核心功能包括: 1. **...

    前端开源库-html-webpack-template

    它支持诸如favicon、meta标签、Google Analytics跟踪代码、自定义脚本和链接等的便捷插入,使得开发者无需手动编写繁琐的HTML模板,而是通过Webpack配置就能轻松定制生成的HTML文件。这对于快速搭建项目原型或者保持...

    前端开源库-html-source-webpack-plugin

    "html-source-webpack-plugin"是HTMLWebpackPlugin的一个扩展,HTMLWebpackPlugin默认会根据Webpack的配置自动生成HTML模板文件,并自动插入bundle.js等Webpack打包后的资源。而"html-source-webpack-plugin"则在...

    webpack-many-page

    - 如`HtmlWebpackPlugin`可自动生成HTML文件,并将打包后的JS自动插入。 二、Webpack配置 Webpack 配置文件(一般为`webpack.config.js`)是实现上述功能的关键。在多页面应用中,配置可能会包括以下部分: 1. `...

    根据webpack4搭的一套空工程已整合hotcss移动端适配方案开箱即用

    - **Plugin**:插件,用于扩展Webpack功能,可以在整个构建过程中执行各种任务。 2. **HotCSS 移动端适配方案** HotCSS 是一种针对移动设备的响应式布局解决方案,它可能包含了以下部分: - **Flexbox布局**:...

    Webpack:webpack练习

    使用 `HtmlWebpackPlugin` 插件,可以在每次构建时自动创建一个 HTML 文件,并将所有必要的脚本和样式插入到该文件中,简化项目部署。 在 `Webpack-master` 这个压缩包中,你可能会找到以下内容: - 一个 `webpack....

    my-scaffold:创建具有完整Webpck设置的应用

    而插件则扩展了Webpack的功能,例如HtmlWebpackPlugin自动在HTML文件中插入打包后的JS引用,或者MiniCssExtractPlugin将CSS提取为单独的文件。 【标签】"JavaScript"表明这个脚手架主要面向JavaScript开发,这意味...

    webpack-tutor

    例如,`HtmlWebpackPlugin` 自动创建一个 HTML 文件并插入打包后的脚本引用,而 `MiniCssExtractPlugin` 可以将 CSS 从 JavaScript 中分离出来,提高页面加载速度。 在 "webpack-tutor" 中,我们还将学习到如何管理...

    electron-vue利用webpack打包实现多页面的入口文件问题

    - **Plugin(扩展插件)**:在 Webpack 构建过程中插入自定义逻辑,实现更复杂的自动化任务,如自动添加版权信息、压缩代码等。 - **Output(输出结果)**:Webpack 处理完所有模块和配置后,将生成的文件输出到指定...

    详解webpack4多入口、多页面项目构建案例

    5. **Plugin(扩展插件)**:Plugin 可以在 Webpack 构建流程的各个阶段插入自定义逻辑,如实现代码压缩、资源合并、HTML模板生成等功能。 6. **Output(输出结果)**:Webpack 处理完所有模块后,会根据配置输出...

    myWebpackMaster

    3. **Plugins**(插件):Webpack 插件是在整个构建过程中的特定时点执行的扩展功能,例如 `HtmlWebpackPlugin` 自动生成 HTML 文件并插入打包后的脚本。 4. **Module Bundling**(模块打包):Webpack 分析所有...

    archived--package-webpack-configs:Webpack配置包

    3. **插件应用**:Webpack插件能扩展Webpack的功能,例如HtmlWebpackPlugin自动创建HTML文件并插入打包后的脚本,MiniCssExtractPlugin将CSS提取到单独的文件中,提高性能。 4. **代码分割与懒加载**:通过配置...

    详解webpack4.x之搭建前端开发环境

    - **html-webpack-plugin**:自动创建HTML文件并插入打包后的脚本。 - **extract-text-webpack-plugin**:将CSS从JS中分离出来,生成单独的CSS文件。 - **uglifyjs-webpack-plugin**:混淆JavaScript代码以提高...

    学习网页包

    例如,HtmlWebpackPlugin 自动创建HTML文件并插入打包后的脚本,MiniCssExtractPlugin则将CSS提取到单独文件以提高性能。 5. **配置优化(Configuration Optimization)**:在实际项目中,我们还需要关注Webpack的...

    webpack-getting-started

    常见的插件有 `HtmlWebpackPlugin`(自动生成 HTML 文件并插入打包后的 JS 文件)和 `MiniCssExtractPlugin`(将 CSS 提取到独立文件)。 ### 6. 配置文件(webpack.config.js) Webpack 的主要配置文件是 `webpack...

Global site tag (gtag.js) - Google Analytics