• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Webpack 自定义插件编写

武飞扬头像
泡泡大怪兽
帮助9

当编写一个自定义插件时,需要知道webpack 插件由以下组成:

  • 一个 JavaScript 命名函数或 JavaScript 类。
  • 在插件函数的 prototype 上定义一个 apply 方法。
  • 指定一个绑定到 webpack 自身的事件钩子。
  • 处理 webpack 内部实例的特定数据。
  • 功能完成后调用 webpack 提供的回调。

基本插件架构

插件是由「具有 apply 方法的 prototype 对象」所实例化出来的。这个 apply 方法在安装插件时,会被 webpack compiler 调用一次。apply 方法可以接收一个 webpack compiler 对象的引用,从而可以在回调函数中访问到 compiler 对象。一个插件结构如下:

  1.  
    class HelloWorldPlugin {
  2.  
    apply(compiler) {
  3.  
    compiler.hooks.done.tap(
  4.  
    'Hello World Plugin',
  5.  
    (
  6.  
    stats /* 绑定 done 钩子后,stats 会作为参数传入。 */
  7.  
    ) => {
  8.  
    console.log('Hello World!');
  9.  
    }
  10.  
    );
  11.  
    }
  12.  
    }
  13.  
     
  14.  
    module.exports = HelloWorldPlugin;

webpack在运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在特定的阶段钩入想要添加的自定义功能。Webpack 的 Tapable 事件流机制保证了插件的有序性,使得整个系统扩展性良好。

  • compiler 暴露了和 Webpack 整个生命周期相关的钩子
  • compilation 暴露了与模块和依赖有关的粒度更小的事件钩子
  • 插件需要在其原型上绑定apply方法,才能访问 compiler 实例
  • 传给每个插件的 compiler 和 compilation对象都是同一个引用,若在一个插件中修改了它们身上的属性,会影响后面的插件
  • 找出合适的事件点去完成想要的功能
    • emit 事件发生时,可以读取到最终输出的资源、代码块、模块及其依赖,并进行修改(emit 事件是修改 Webpack 输出资源的最后时机)
    • watch-run 当依赖的文件发生变化时会触发
  • 异步的事件需要在插件处理完任务时调用回调函数通知 Webpack 进入下一个流程,不然会卡住

最近一个项目需要在每次打包发版后判断当前的版本号是不是最新的,从而提示用户版本已经更新。实现思路就是每次构建打包时将package.json里的版本号取出来,打包时自动生成一个json的静态文件放在打包好的目录里,这样就可以动态的取这个文件里的版本号与项目里的版本号比对是否一致,判断当前的代码是不是最新的。

创建自定义插件

这里以vue项目为例,在项目目录下创建一个js文件extra-webpack-plugin.js来存放插件的代码

  1.  
    /** 自定义的插件: 生成版本号json文件 */
  2.  
    const { version } = require("./package.json");
  3.  
    const fs = require("fs");
  4.  
    class VersionPlugin {
  5.  
      apply(compiler) {
  6.  
    // emit 是异步 hook,使用 tapAsync 触及它,还可以使用 tapPromise/tap(同步)
  7.  
        compiler.hooks.emit.tap("Version Plugin", (compilation) => {
  8.  
          const outputPath = compiler.path || compilation.options.output.path;
  9.  
          const versionFile = outputPath "/version.json";
  10.  
          const content = `{"version": "${version}"}`;
  11.  
     
  12.  
          /** 如果路径存在则返回 true,否则返回 false。 */
  13.  
          if (!fs.existsSync(outputPath)) {
  14.  
            // 同步地创建目录。 返回 undefined 或创建的第一个目录路径(如果 recursive 为 true)。 这是 fs.mkdir() 的同步版本。
  15.  
            fs.mkdirSync(outputPath, { recursive: true });
  16.  
          }
  17.  
     
  18.  
          // http://nodejs.cn/api-v14/fs.html#fs_fs_writefilesync_file_data_options
  19.  
          fs.writeFileSync(versionFile, content, {
  20.  
            encoding: "utf8",
  21.  
            flag: "w",
  22.  
          });
  23.  
        });
  24.  
      }
  25.  
    }
  26.  
     
  27.  
    module.exports = { VersionPlugin };
学新通

如何使用自定义插件

要安装这个插件,只需要在你的 vue.config.js 配置的 plugin 数组中添加一个实例,这样打包运行时就会执行这个自定义插件,打包完成后会在dist目录下生成一个version.json的文件。

  1.  
    const { VersionPlugin } = require('./extra-webpack-plugin');
  2.  
     
  3.  
    const vueConfig = {
  4.  
        publicPath: process.env.VUE_PUBLIC_PATH || '/',
  5.  
        configureWebpack: {
  6.  
            plugins: [
  7.  
                // 自定义插件
  8.  
                new VersionPlugin()
  9.  
            ]
  10.  
        }
  11.  
    }
  12.  
     
  13.  
    module.exports = vueConfig

以上是对webpack自定义插件的简单的尝试,具体用法和其他API可以参考官方文档。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhejkkkf
系列文章
更多 icon
同类精品
更多 icon
继续加载