Webpack 什么是loader?什么是plugin?loader与plugin区别是什么?

什么是loader?什么是plugin?

  • loader 本质为一个函数,将文件编译成可执行文件。webpack完成的工作是将依赖分析与tree shinking对于类似.vue或.scss结尾的文件无法编译理解这就需要实现一个loader完成文件转译成js、html、css、json等可执行文件。
  • plugin可以是函数或Class(es6),通过订阅webpack串行流程上的事件,实现扩展webpack功能,改变webpack输出结果。

区别:

  1. 执行时机不同。loader主要是倒序执行,从后往前将一个loader的输出作为它前一个loader的输入,直到运行完所有loader;plugin执行执行时机在与通过订阅webpack串行流程上的事件,当webpack运行到对应订阅事件时执行,可以运行在整个生命周期内。两者都可以同步或者异步执行。
  2. 侧重功能不同。loader主要完成文件操作;plugin主要是实现除loader以外功能,扩展webpack功能。
  3. 配置方式不同。loader配置到module.rules,rules是一个数组,每一个元素是一个对象,每个对象包含属性test(检验目标文件类型)、use:(loader数组,从后往前执行)、options(配置);plugin放在plugins数组中通过new 关键字创建。
  4. 书写方式不同。

​ loader编写伪代码如下

js 复制代码
/**
 * 定义一个loader
 * 1.不可为一个箭头函数,Webpack运行时需要指定运行this为Webpack,所以可以调用内置api
 * 2.可以异步返回使用this.callback
 * 3.配置的options可以使用this.query获取
 * @param source 模块文件源数据内容
 * @return {*}
 */
module.exports = function (source) {

  // 如果 loader 配置了 options 对象,那么this.query将指向 options
  const options = this.query;

  const doTask = async (source) => {
    //伪代码进行数据转换
    const content = await source2Something(source,options)
    /*
    * this.callback 参数:
    * error:Error | null,当 loader 出错时向外抛出一个 error
    * content:String | Buffer,经过 loader 编译后需要导出的内容
    * sourceMap:为方便调试生成的编译后内容的 source map
    * ast:本次编译生成的 AST 静态语法树,之后执行的 loader 可以直接使用这个 AST,进而省去重复生成 AST 的过程
    */
    this.callback(null, content)
  }

  //异步返回结果
  doTask()
  //同步返回
  return source2Something(source,options)
}

​ plugin编写伪代码如下

js 复制代码
/**
 * 定义一个plugin
 * 1.需要通过new创建可以使用class创建
 * 2.内部需要有一个方法apply调用运行插件功能
 * 
 * 具体可以看
 * https://webpack.docschina.org/contribute/writing-a-plugin/#basic-plugin-architecture
 */

class MyPlugin {
  //创建时可以传入参数
  constructor(options) {
    this.options = options;
  }

  /**
   * 通过compiler获取 webpack 内部的钩子,获取 webpack 打包过程中的各个阶段
   * 钩子分为同步和异步的钩子,异步钩子必须执行对应的回调
   * @param compiler
   */
  apply(compiler){
    //同步hook 最后调用tap
    //emit为hook事件名称
    compiler.hooks.emit.tap('MyPlugin',compilation=>{

      //do somethings
      //do somethings
      //do somethings

    })
    //异步hook 最后调用tapAsync、tapPromise
    //done为hook事件名称
    //tapAsync 异步钩子必须执行对应的回调
    //tapPromise 需要返回Promise
    compiler.hooks.done.tap('MyPlugin', (compilation, callback) => {
      console.log("打包已完成");

      //do somethings
      //do somethings
      //do somethings

      callback();
    })
  }

}
相关推荐
小兵张健2 小时前
价值1000的 AI 工作流:Codex 通用前端协作模式
前端·aigc·ai编程
sunny_2 小时前
面试踩大坑!同一段 Node.js 代码,CJS 和 ESM 的执行顺序居然是反的?!99% 的人都答错了
前端·面试·node.js
拉不动的猪3 小时前
移动端调试工具VConsole初始化时的加载阻塞问题
前端·javascript·微信小程序
ayqy贾杰4 小时前
Agent First Engineering
前端·vue.js·面试
IT_陈寒4 小时前
SpringBoot实战:5个让你的API性能翻倍的隐藏技巧
前端·人工智能·后端
iceiceiceice5 小时前
iOS PDF阅读器段评实现:如何从 PDFSelection 精准还原一个自然段
前端·人工智能·ios
大金乄5 小时前
封装一个vue2的elementUI 表格组件(包含表格编辑以及多级表头)
前端·javascript
葡萄城技术团队6 小时前
【性能优化篇】面对万行数据也不卡顿?揭秘协同服务器的“片段机制 (Fragments)”
前端
程序员阿峰6 小时前
2026前端必备:TensorFlow.js,浏览器里的AI引擎,不写Python也能玩转智能
前端
Jans6 小时前
Shipfe — Rust 写的前端静态部署工具:一条命令上线 + 零停机 + 可回滚 + 自动清理
前端