实践-写一个简单的 webpack plugin

604 阅读1分钟

这里实现了一个简单的 htmlWebpackPlugin,来帮助我们理解 plugin 的运行机制。

htmlWebpackPlugin

htmlWebpackPlugin 用于在打包时生成一个 html 文件,并将输出的JS文件引入到 script 标签中。

代码如下:

class HtmlWebpackPlugin {
  constructor(options = {}) {
    this.options = options;
  }

  apply(compiler) {
    // Webpack 注册 plugin 时会执行它的 apply 方法
    const pluginName = HtmlWebpackPlugin.name;

    const { RawSource } = compiler.webpack.sources;

    // Tapping to the "thisCompilation" hook in order to further tap
    // to the compilation process on an earlier stage.
    compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
      const outputJSFile = compilation.options.output.filename;
      const ouputContent = `
        <html>
            <head>
                <meta charset="utf-8" />
                <title>Webpack App</title>
                <meta name="viewport" content="width=device-width,initial-scale=1" />
                <script defer="defer" src="${outputJSFile}"></script> 
            </head>
            <body></body>
        </html>
      `;
      // Tapping to the assets processing pipeline on a specific stage.
      compilation.hooks.processAssets.tap(
        {
          name: pluginName,
        },
        () => {
          compilation.emitAsset('index.html', new RawSource(ouputContent)); // 添加一个新的 asset
        },
      );
    });
  }
}

module.exports = { HtmlWebpackPlugin };

webpack.config.js 中引入:

const { HtmlWebpackPlugin } = require('./plugins/htmlWebpackPlugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'bundle.js',
  },
  plugins: [new HtmlWebpackPlugin()], // 引入 HtmlWebpackPlugin
};

需要注意的是,plugin 中需要实现一个 apply 方法,在其中可以订阅一些事件(webpack的事件发布订阅基于 tapable),并设置回调函数,它会在 webpack 运行的特定阶段触发。

参考 Writing a Plugin