【webpack 从入门到使用】插件 plugin

说明

  1. 这套笔记是对于 webpack 5.x 进行阐述的。(webpack <= 4 用法稍有不同)

概述:

插件是 webpack支柱功能。Webpack 自身也是构建于你在 webpack 配置中用到的相同的插件系统之上!

plugin 和 loader 的不同

loader 是为了解决 webpack 内置功能不足而进行的扩展,而 plugin 是在 webpack 自身的 compiler 上监听和操作流程。

plugin 的特点

  1. webpack 插件是一个具有 apply 方法的 JavaScript 对象。apply 方法会被 webpack compiler 调用,并且在 整个编译生命周期都可以访问 compiler 对象。
  2. 为什么 webpack 的插件大多数是用 class 写的呢?由于插件可以携带参数/选项,你必须在 webpack 配置中,向 plugins 属性传入一个 new 实例。(取决于你的 webpack 用法,对应有多种使用插件的方式。)

常用的插件

插件名称 插件说明
html-webpack-plugin 在 webpack 运行时创建一个带有打包好的 js 的 html 文件的 plugin
vue-loader.VueLoaderPlugin 解析 vue SFC 文件的 plugin 的plugin
clean-webpack-plugin 清除上一次打包内容的 plugin
mini-css-extract-plugin 提取样式到 css 文件中
css-minimizer-webpack-plugin 压缩 css 文件
uglifyjs-webpack-plugin 压缩 js 文件的 plugin (webpack 3 以前使用)
terser-webpack-plugin 压缩 js 文件的 plugin
clean-webpack-plugin 清空之前打包的内容(webpack5 内置)

html-webpack-plugin 为例:

js 复制代码
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // ...
  
  new HtmlWebpackPlugin({
    template: resolve(__dirname, 'public/index.html'),
    filename: 'index.html',
    title: '首页',
    chunks: ['index'],
    excludeChunks: ['node_modules'],
    minify: {
      removeComments: true,
      collapseWhitespace: true
    }
  })
  
  // ...
};

如果我想写一个插件,怎么办?

实现思路

  • webpack 的 plugins 属性接收一个数组,里面都是一个含有 apply 方法(包含形参 compiler 对象)的对象
  • webpack 的插件基本上都是 new 出来的

所以,我们可以写一个包含 apply 成员方法的一个类来实现一个我们的插件。

具体步骤

以实现 TestPlugin 为例:

markdown 复制代码
|- plugins # 插件目录
    |- test-plugin
        |- index.js # 导出 TestPlugin 的文件
        |- ...
    |- ... # 其他自定义插件
|- src
    |- ... # 业务代码
|- webpack.config.js
  1. 写一个包含 apply 成员方法的类,命名为 TestPlugin 并导出
js 复制代码
class TestPlugin {
  constructor(options) {
    this.userOptions = options || {}; // 接收用户传递过来的插件
    this.pgName = 'TestPlugin'; // 默认配置 name
    this.version = '1.0.0'; // 默认配置 version
  }
  
  /** @param {import('webpack').Compiler} compiler */
  apply(compiler) {
    console.log("this.userOptions", this.userOptions);
    const { pgName, version } = this;
    compiler.hooks.run.tap(pgName, (compilation) => { // compilation === compiler -> true
      console.log();
      console.log('🔥🔥🔥 正在启用 TestPlugin !!! 🔥🔥🔥 ');
      console.log(`
参数:
      名称:"${pgName}"
      版本:"${version}"
      `);
      console.log('====  开始走流程。。。 ====');
      console.log('====  流程走完了!!! ====');
      console.log('==== 🔥🔥🔥 TestPlugin 启用完毕 !!! ==== 🔥🔥🔥 ');
    });
  }
}

module.exports = new TestPlugin();
module.exports.TestPlugin = TestPlugin;
  1. webpack.config.js 注册一下这个插件
js 复制代码
const { TestPlugin } = require('./plugins/test-plugin');

const config = {
  // ...
  plugins: [
    // ...
    new TestPlugin({
      foo: 'Foo'
    })
  ],
  // ...
};

module.exports = config;
相关推荐
kyriewen6 小时前
Anthropic 估值逼近万亿美元,Claude Sonnet 5 + Claude Science 一天两连发
前端·ai编程·claude
小徐_23337 小时前
Wot UI 2.2.0 发布:Button 新增 subtle,VideoPreview 预览体验继续增强
前端·微信小程序·uni-app
天蓝色的鱼鱼10 小时前
关于 CSS 你可能不知道的属性,但关键时刻很有用
前端·css
泯泷10 小时前
第 2 篇:设计第一套字节码:Opcode、Instruction 与 Constant Pool
前端·javascript·安全
妙码生花10 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十五):优化细节、网络请求封装
前端·后端·ai编程
泯泷10 小时前
第 1 篇:从 1 + 2 开始:亲手写出第一台 JSVM
前端·javascript·安全
团团崽_七分甜10 小时前
Spring Boot 核心知识点总结
前端
lichenyang45311 小时前
从一个按钮开始,理解 ASCF 框架到底在做什么
前端
古夕11 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js