【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;
相关推荐
曼巴UE52 小时前
UE FString, FName ,FText 三者转换,再次学习,官方文档理解
服务器·前端·javascript
行走的陀螺仪3 小时前
高级前端 Input 公共组件设计方案(Vue3 + TypeScript)
前端·javascript·typescript·vue·组件设计方案
一颗不甘坠落的流星3 小时前
【Antd】基于 Upload 组件,导入Json文件并转换为Json数据
前端·javascript·json
LYFlied3 小时前
Vue2 与 Vue3 虚拟DOM更新原理深度解析
前端·javascript·vue.js·虚拟dom
Lucky_Turtle3 小时前
【Node】npm install报错npm error Cannot read properties of null (reading ‘matches‘)
前端·npm·node.js
小飞侠在吗4 小时前
vue shallowRef 与 shallowReacitive
前端·javascript·vue.js
惜分飞4 小时前
sql server 事务日志备份异常恢复案例---惜分飞
前端·数据库·php
GISer_Jing4 小时前
WebGL实例化渲染:性能提升策略
前端·javascript·webgl
烟锁池塘柳05 小时前
【技术栈-前端】告别“转圈圈”:详解前端性能优化之“乐观 UI” (Optimistic UI)
前端·ui