Vite: Rollup 的插件机制

概述

  • 仅仅使用 Rollup 内置的打包能力很难满足项目日益复杂的构建需求
  • 对于一个真实的项目构建场景来说,我们还需要考虑到 模块打包 之外的问题,比如路径别名(alias) 、全局变量注入和代码压缩等等
  • 可要是把这些场景的处理逻辑与核心的打包逻辑都写到一起,一来打包器本身的代码会变得十分臃肿,二来也会对原有的核心代码产生一定的侵入性,混入很多与核心流程无关的代码,不易于后期的维护
  • 因此 ,Rollup 设计出了一套完整的插件机制,将自身的核心逻辑与插件逻辑分离,让你能按需引入插件功能,提高了 Rollup 自身的可扩展性。Rollup 的插件机制,功能完备又简单易上手,体现了 Rollup 本身小而美的风格
  • Rollup 的打包过程中,会定义一套完整的构建生命周期,从开始打包到产物输出,中途
    会经历一些标志性的阶段,并且在不同阶段会自动执行对应的插件钩子函数(Hook)
  • 对Rollup 插件来讲,最重要的部分是钩子函数,一方面它定义了插件的执行逻辑,也就是"做什么";另一方面也声明了插件的作用阶段,即"什么时候做",这与 Rollup 本身的构建生命周期息息相关
  • 因此,要真正理解插件的作用范围和阶段,首先需要了解 Rollup 整体的构建过程中到底
    做了些什么

Rollup 整体构建阶段

  • 在执行 rollup 命令之后,在 cli 内部的主要逻辑简化如下:
    // Build 阶段
    const bundle = await rollup.rollup(inputOptions);
    // Output 阶段
    await Promise.all(outputOptions.map(bundle.write));
    // 构建结束
    await bundle.close();
    
  • Rollup 内部主要经历了 Build 和 Output 两大阶段:
  • 首先,Build 阶段主要负责创建模块依赖图,初始化各个模块的 AST 以及模块之间的依
    赖关系。下面我们用一个简单的例子来感受一下:

    // src/index.js
    import {
         
          a } from './module-a';
    console.log(a);
    // src/module-a.js
    export const a = 1;
    
  • 然后执行如下的构建脚本

    const rollup = require('rollup');
    const util = require('util');
    async function build() {
         
         
     const bundle = await rollup.rollup({
         
         
     input: ['./src/index.js'],
     });
     console.log(util.inspect(bundle));
    }
    build();
    
  • 可以看到这样的 bundle 对象信息

    {
         
         
      cache: {
         
         
        modules: [{
         
         
            ast: 'AST 节点信息,具体内容省略',
            code: 'export const a = 1;',
            dependencies: [],
            id: '/Users/code/rollup-demo/src/data.js',
            // 其它属性省略
          },
          {
         
         
            ast: 'AST 节点信息,具体内容省略',
            code: "import { a } from './data';\n\nconsole.log(a);",
            dependencies: [
              '/Users/code/rollup-demo/src/data.js'
            ],
            id: '/Users/code/rollup-demo/src/index.js',
            // 其它属性省略
          }
        ],
        plugins: {
         
         }
      },
      closed: false,
      // 挂载后续阶段会执行的方法
      close: [AsyncFunction: close],
      generate: [AsyncFunction: generate],
      write: [AsyncFunction: write]
    }
    
  • 从上面的信息中可以看出,目前经过 Build 阶段的 bundle 对象其实并没有进行模块的
    打包,这个对象的作用在于存储各个模块的内容及依赖关系,同时暴露 generate 和
    write 方法,以进入到后续的 Output 阶段( write 和 generate 方法唯一的区别在于前
    者打包完产物会写入磁盘,而后者不会)。

  • 所以,真正进行打包的过程会在 Output 阶段进行,即在 bundle 对象的 generate 或者
    write 方法中进行。还是以上面的 demo 为例,我们稍稍改动一下构建逻辑:

    const rollup = require('rollup');
    async function build
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值