如何编写一个 webpack plugin

本篇文章源自我自己的一个需求:我想看看 webpack 是如何组织 js 代码模块化的。打开编译后的文件有很多注释,不方便查看,我想去掉这些这些注释,那应该怎么做呢?学习写个插件用正则替换这些注释代码。

插件的设计机制一般都是在程序运行的各个阶段提供不同的 hook,传入数据、修改数据,以期得到一个满意的结果,webpack 也不例外。那针对这种场景,应该使用说明钩子函数呢?

webpack 也在一个变量里保存了所有的模块,细节和 seajs 差不多。这个简单的插件代码如下:

class MyExampleWebpackPlugin {
  // 每个插件都要定义一个 apply 方法
  apply(compiler) {
    // emit 钩子表示资源保存到文件夹触发
    compiler.hooks.emit.tapAsync(
      "MyExampleWebpackPlugin",
      (compilation, callback) => {
        // 拿到 bundle.js 的源文件
        let source = compilation.assets["bundle.js"].source();
        console.log(source);

        source = source.replace(/\/\*\*{1,}\*\/\s?/gm, "");
        // source = source.replace(/\s\/\/.{1,}[\r\n]/g, "");
        source = source.replace(
          /var installedModules = {}/g,
          "var installedModules = window.installedModules = {}"
        );

        compilation.assets["bundle.js"] = {
          source() {
            // 写入替换之后的源文件
            return source;
          },
          size() {
            return source.length;
          },
        };

        callback();
      }
    );
  }
}

module.exports = MyExampleWebpackPlugin;

编写插件比编写 loader 需要了解 webpack 更底层的一些设计,甚至可能需要去看 webpack 的源码。

扩展阅读

我要分享

曾小乱

作者: 曾小乱

喜欢写点有意思的东西

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据