深入了解rollup(三)插件机制

简介: Rollup 插件是一个对象,具有属性]、构建钩子 和 输出生成钩子 中的一个或多个,并遵循我们的约定。插件应作为一个导出一个函数的包进行发布,该函数可以使用插件特定的选项进行调用并返回此类对象。插件允许你通过例如在打包之前进行转译代码或在node_modules文件夹中查找第三方模块来自定义 Rollup 的行为。

引言

Rollup是一个JavaScript模块打包器,它可以将多个模块打包成一个单独的文件,以便在浏览器中使用。与其他打包工具相比,Rollup的主要优势在于它可以生成更小、更快的代码。在本文中,我们将深入了解Rollup的插件机制。

rollup插件机制概述

Rollup 插件是一个对象,具有属性]构建钩子输出生成钩子 中的一个或多个,并遵循我们的约定。插件应作为一个导出一个函数的包进行发布,该函数可以使用插件特定的选项进行调用并返回此类对象。

插件允许你通过例如在打包之前进行转译代码或在node_modules文件夹中查找第三方模块来自定义 Rollup 的行为。

属性

  • name: 插件的名称,用于在警告和错误消息中标识插件。
  • version: 插件的版本,用于插件间通信场景。

约定

  • 插件应该有一个明确的名称,并以rollup-plugin-作为前缀。
  • package.json中包含rollup-plugin关键字。
  • 如果插件使用“虚拟模块”(例如用于辅助函数),请使用\0前缀模块 ID。这可以防止其他插件尝试处理它。

构建钩子执行方式

钩子是在构建的各个阶段调用的函数。钩子可以影响构建的运行方式,提供关于构建的信息,或在构建完成后修改构建。有不同种类的钩子:

  • async:该钩子也可以返回一个解析为相同类型的值的 Promise;否则,该钩子被标记为 sync
  • first:如果有多个插件实现此钩子,则钩子按顺序运行,直到钩子返回一个不是 nullundefined 的值。
  • sequential:如果有多个插件实现此钩子,则所有这些钩子将按指定的插件顺序运行。如果钩子是 async,则此类后续钩子将等待当前钩子解决后再运行。
  • parallel:如果有多个插件实现此钩子,则所有这些钩子将按指定的插件顺序运行。如果钩子是 async,则此类后续钩子将并行运行,而不是等待当前钩子。

除了函数之外,钩子也可以是对象。在这种情况下,实际的钩子函数必须指定为 handler。这允许你提供更多的可选属性,以改变钩子的执行:

  • order: "pre" | "post" | null

如果有多个插件实现此钩子,则可以先运行此插件("pre"),最后运行此插件("post"),或在用户指定的位置运行(没有值或 null)。

exportdefaultfunctionresolveFirst() {
return {
name: 'resolve-first',
resolveId: {
order: 'pre',
handler(source) {
console.log(source);
returnnull;
      }
    }
  };
}

输出生成钩子

输出生成钩子可以提供有关生成的产物的信息并在构建完成后修改构建。它们的工作方式和类型与 构建钩子 相同,但是对于每个调用 bundle.generate(outputOptions)bundle.write(outputOptions),它们都会单独调用。仅使用输出生成钩子的插件也可以通过输出选项传递,并且因此仅针对某些输出运行。

钩子执行顺序

  1. 通过 options 钩子读取配置,并进行配置的转换,得到处理后的配置对象。
  2. 调用 buildStart 钩子,考虑了所有 options钩子配置的转换,包含未设置选项的正确默认值,正式开始构建流程。
  3. 调用 resolveId 钩子解析模块文件路径。rollup中模块文件的id就是文件地址,所以,类似resolveId这种就是解析文件地址的意思。从inputOptioninput配置指定的入口文件开始,每当匹配到引入外部模块的语句(如:import moudleA from './moduleA')便依次执行注册插件中的每一个 resolveId 钩子,直到某一个插件中的 resolveId 执行完后返回非 null 或非 undefined 的值,将停止执行后续插件的 resolveId 逻辑并进入下一个钩子。
  4. 调用load钩子加载模块内容,resolveId中的路径一般为相对路径,load中的路径为处理之后的绝对路径。
  5. 接着判断当前解析的模块是否存在缓存,若不存在则执行所有的 transform 钩子来对模块内容进行进行自定义的转换;若存在则判断shouldTransformCachedModule属性,true则执行所有的 transform 钩子,false则进入moduleParsed钩子逻辑。。
  6. 拿到最后的模块内容,进行 AST 分析,调用 moduleParsed 钩子。如果内部没有imports内容,进入buildEnd环节。如果还有imports内容则继续,如果是普通的 import,则执行resolveId 钩子,继续回到步骤3-调用resolveId;如果是动态 import,则执行resolveDynamicImport 钩子解析路径,如果解析成功,则回到步骤4-load加载模块,否则回到步骤3通过 resolveId 解析路径。
  7. 直到所有的 import 都解析完毕,Rollup 执行buildEnd钩子,Build阶段结束。

插件示例

// rollup-plugin-example.jsexportdefaultfunctionmyExample () {
return {
name: 'my-example',
options (options) {
console.log({ options })
    },
buildStart (options) {
console.log("buildStart:", options)
    },
resolveId (source,importer) {
console.log("resolveId(source):", source)
console.log("resolveId(importer):", importer)
returnnull; 
    },
load (id) {
console.log({ id })
returnnull; 
    },
transform(code,id) {
console.log("transform");
console.log("---",code)
console.log("---",id)
    },
moduleParsed (info) {
console.log("moduleParsed:", info)
    },
buildEnd() { 
console.log("buildEnd");
    }
  };
}

调用虚拟模块插件示例

constvirtualModuleId='virtual-module';
// rollup约定插件使用“虚拟模块”,使用\0前缀模块 ID。这可以防止其他插件尝试处理它。constresolvedVirtualModuleId='\0'+virtualModuleId;
exportdefaultfunctionvirtualModule() {
return {
name: 'virtual-module', 
resolveId (source) {
if (source==='virtual-module') { 
returnresolvedVirtualModuleId; // 告诉Rollup,这个ID是外部模块,不要在此处查找它      }
returnnull; // 其他ID应按通常方式处理    },
load (id) {
console.log({ id })
if (id===resolvedVirtualModuleId) { 
// return 'export default "This is virtual!"'; // 告诉Rollup,如何加载此模块return'export default function fib(n) { return n <= 1 ? n : fib(n - 1) + fib(n - 2); }'      }
returnnull; // 其他ID应按通常方式处理    },
  };
}

界面调用

// index.jsimportfibfrom"virtual-module";
console.log(fib(10))

build之后

// index.jsfunctionfib(n) {returnn<=1?n : fib(n-1) +fib(n-2)}
console.log(fib(10));

总结

Rollup的插件机制通过定义钩子函数来扩展其功能,钩子函数在不同的阶段执行不同的操作。开发者可以根据自己的需求编写自定义插件,并将其添加到Rollup配置中。通过使用插件机制,可以实现各种功能扩展,例如修改配置选项、解析模块路径、加载模块内容、转换模块代码等。

目录
相关文章
|
定位技术
GPS北斗卫星同步时钟(时间同步服务器)建设施工部署方案
GPS北斗卫星同步时钟(时间同步服务器)建设施工部署方案
409 10
GPS北斗卫星同步时钟(时间同步服务器)建设施工部署方案
【el-tree】树形结构拖拽,拖动修改分组
【el-tree】树形结构拖拽,拖动修改分组
1111 1
|
资源调度 JavaScript 前端开发
【TypeScript】TS 看这一篇就够了
【TypeScript】TS 看这一篇就够了
1394 0
|
存储 弹性计算 安全
使用OSS上传下载文件
阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,可以提供多种用途,最简单的使用方式是做文件存储,用来上传下载文件啊
4200 0
使用OSS上传下载文件
|
3月前
|
缓存 前端开发 JavaScript
如何配置Vite以确保最佳的Tree Shaking效果?
如何配置Vite以确保最佳的Tree Shaking效果?
539 56
|
3月前
|
供应链 数据可视化 安全
如何用低代码平台自己开发一个进销存的系统?
本文介绍了如何利用低代码平台(如简道云)快速搭建企业进销存系统,解决传统ERP成本高、灵活性差的问题。内容涵盖适用场景、核心模块设计(商品信息、采购入库、销售出库)、库存看板与权限设置,并提供时间与成本参考,助力小团队高效实现个性化管理。
|
存储 消息中间件 缓存
Redis缓存技术详解
【5月更文挑战第6天】Redis是一款高性能内存数据结构存储系统,常用于缓存、消息队列、分布式锁等场景。其特点包括速度快(全内存存储)、丰富数据类型、持久化、发布/订阅、主从复制和分布式锁。优化策略包括选择合适数据类型、设置过期时间、使用Pipeline、开启持久化、监控调优及使用集群。通过这些手段,Redis能为系统提供高效稳定的服务。
|
JavaScript 前端开发 开发者
深入了解rollup(一)快速开始
Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由无缝地组合你最喜欢的库中最有用的个别函数。这在未来将在所有场景原生支持,但 Rollup 让你今天就可以开始这样做。
197 0
|
SQL 缓存 架构师
一文梳理Code Review方法论与实践总结
作为卓越工程文化的一部分,Code Review其实一直在进行中,只是各团队根据自身情况张驰有度,松紧可能也不一,这里简单梳理一下CR的方法和团队实践。
61225 11
一文梳理Code Review方法论与实践总结
|
存储 缓存 编解码
pnpm 中的 .npmrc 文件配置
.npmrc 文件是一个使用 .ini 文件格式书写的配置文件。本文介绍pnpm 中的 .npmrc 文件配置方法。
3192 0
pnpm 中的 .npmrc 文件配置