【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;
相关推荐
M ? A13 分钟前
Vue 的 scoped 样式穿透 React 不支持?用 VuReact 编译就行
前端·javascript·vue.js·react.js·面试·开源·vureact
zs宝来了14 分钟前
Vue 3 Composition API:响应式系统与依赖追踪
前端·javascript·框架
李伟_Li慢慢18 分钟前
wolfram详解山峦算法
前端·算法
村上小树28 分钟前
非常简单地学习一下slate.js的原理
前端·javascript
web打印社区31 分钟前
[特殊字符] 开源好物:web-print-pdf,让 Web 打印像调用接口一样简单!
前端·javascript·vue.js·electron
嗷o嗷o34 分钟前
Android BLE 收到字节流以后,为什么业务状态还是不对
前端
莪_幻尘37 分钟前
Prompt 工程化落地:从"手工咒语"到工业级软件系统
前端
荒天帝38 分钟前
Android App 最强APM来袭
前端
vim怎么退出39 分钟前
我给 Claude Code 写了一个自适应学习 Skill,7 天刷完浏览器原理
前端·人工智能
逍遥归来41 分钟前
UICollectionViewDiffableDataSource 刷新方案总结
前端