• 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编写伪代码如下

    /**
     * 定义一个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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    ​ plugin编写伪代码如下

    /**
     * 定义一个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();
        })
      }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

  • 相关阅读:
    New Work New Life
    JAVA计算机毕业设计游戏分享平台Mybatis+源码+数据库+lw文档+系统+调试部署
    第一张是论文里面的运算过程,我的运算过程会出现里面的穿透外面那层,想要护腿进去的时候是能包裹住腿的
    微服务:高性能网关 ShenYu简介
    ucos2源码分析---内核部分(三)
    int* p[10]和(int*) p[10]的区别
    Linux扩展根目录容量
    全球首度引入AI!腾讯主导的新一代实时语音编码标准AVS3P10即将发布
    11月第1周榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩)发布!
    Ubuntu Server 20.04 LTS 环境下搭建vim 编辑器Python IDE
  • 原文地址:https://blog.csdn.net/TY_GYY/article/details/133807986