深入了解rollup(一)快速开始

简介: Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由无缝地组合你最喜欢的库中最有用的个别函数。这在未来将在所有场景原生支持,但 Rollup 让你今天就可以开始这样做。

引言

Rollup是一个JavaScript模块打包器,它可以将多个模块打包成一个单独的文件,以便在浏览器中使用。与其他打包工具相比,Rollup的主要优势在于它可以生成更小、更快的代码。在本文中,我们将深入了解Rollup的工作原理、使用方法、摇树优化(tree shaking)。



概览

Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由无缝地组合你最喜欢的库中最有用的个别函数。这在未来将在所有场景原生支持,但 Rollup 让你今天就可以开始这样做。

工作原理

1. 解析入口文件:Rollup首先会解析指定的入口文件,找到其中的导入语句和导出语句。它会构建一个模块依赖图,记录每个模块之间的依赖关系。

2. 递归解析依赖:Rollup会递归地解析每个模块的依赖关系,直到所有依赖都被解析完毕。这样就可以构建出完整的模块依赖图。

3. Tree Shaking:在构建完模块依赖图后,Rollup会进行Tree Shaking操作。它会分析每个模块中导出和导入的变量,并标记哪些变量被使用了。然后,在生成最终文件时,只有被标记为使用过的变量才会被保留下来。这样可以消除未使用的代码,减少最终文件的大小和加载时间。

4. 模块合并:根据模块依赖图和Tree Shaking结果,Rollup将所有需要保留下来的代码合并成一个或多个文件。这些文件可以是ES6模块、CommonJS模块或AMD模块等不同格式。

5. 输出最终文件:最后,Rollup将合并后的代码输出到指定的文件中。可以通过配置选项来指定输出文件的路径、格式和名称等。

Rollup的工作原理与其他打包工具类似,但它的Tree Shaking技术使得生成的代码更小、更高效。通过消除未使用的代码,Rollup可以生成更精简、更快速的JavaScript文件,提高应用程序的性能和加载速度。

快速开始

安装rollup

全局安装

npm install -g rollup

项目安装

npm install -D rollup

基本命令行

查看可用选项和参数

npx rollup -h

部分可用选项和参数:

demo示例

.
├── package.json
└── src
    ├── index.js
    └── util.js

index.js

import { getRandomNum } from"./util.js";
constr=getRandomNum(1, 10)
console.log(r)

util.js

/** * 随机数 * @param {*} min 最小值 * @param {*} max 最大值 * @returns min-max之间的随机整数 */exportconstgetRandomNum= (min, max) => {
min=Math.ceil(min);
max=Math.floor(max);
returnMath.floor(Math.random() * (max-min+1)) +min;
}
/** * 深拷贝 * @param obj 需要深拷贝的对象 * @returns 深拷贝对象 */exportconstdeepClone= (obj) => {
if(typeofobj!=='object'||obj===null) {
returnobj  }
constresult=Array.isArray(obj) ? [] : {};
for(letkeyinobj) {
if(obj.hasOwnProperty(key)) {
result[key] =deepClone(obj[key])
    }
  }
returnresult}
exportdefault {getRandomNum,deepClone}

执行命令输出到bundle.js

npx rollup src/index.js --file dist/bundle.js

可以看到打印结果基本和源码相差不大,而且,自动做了摇树优化,也就是把没有用到的代码自动的删除了。

dist/bundle.js

/** * 随机数 * @param {*} min 最小值 * @param {*} max 最大值 * @returns min-max之间的随机整数 */constgetRandomNum= (min, max) => {
min=Math.ceil(min);
max=Math.floor(max);
returnMath.floor(Math.random() * (max-min+1)) +min;
};
constr=getRandomNum(1, 10);
console.log(r);

另外还可以选择编译的格式:

对于浏览器:

# 编译为包含自执行函数('iife')的 <script>。npx rollup src/index.js --file dist/bundle.js --format iife

对于 Node.js:

# 编译为一个 CommonJS 模块 ('cjs')npx rollup src/index.js --file dist/bundle.js --format cjs

对于浏览器和 Node.js:

# UMDnpx rollup src/index.js --file dist/bundle.js --format umd

摇树优化(tree shaking)

除了可以使用 ES 模块之外,Rollup 还可以静态分析你导入的代码,并将排除任何实际上没有使用的内容,这使你可以在现有的工具和模块的基础上构建,而不需要添加额外的依赖项或使项目的大小变得臃肿。从上面的引入和最后的打包结果就可以看到,没有使用到的deepClone直接被删除了。

注意,摇树优化的核心思想是在编译阶段通过静态分析确定代码的使用情况,而不是在运行时

所以摇树优化一般是建立在ES6 模块化语法基础之上的,ESM的导入导出是静态的。

CommonJS 模块的导入和导出是动态的,无法在编译阶段静态确定代码的使用情况。一般情况下,摇树优化工具无法在 CommonJS 模块中进行精确的摇树,因为无法静态分析模块间的导入和导出关系。

然而,一些构建工具(如 Webpack)会尝试通过静态分析和启发式方法对 CommonJS 模块进行近似的摇树优化。它们会尽可能地识别出那些可以在编译阶段确定未被使用的代码,并进行剔除。但这种处理方式可能不如对 ES6 模块的优化效果好,且有一定的限制。

摇树优化的原理:

Tree Shaking是一种用于消除未使用代码的优化技术,它在打包过程中只保留被实际使用的代码,从而减少最终生成的文件大小。Tree Shaking的原理可以分为以下几个步骤:

1. 识别依赖关系:在打包过程中,工具(如Rollup)会分析每个模块中的导入和导出语句,构建出一个模块依赖图。这个图记录了每个模块之间的依赖关系。

2. 标记被使用的代码:通过静态分析技术,工具会遍历依赖图,并标记哪些变量、函数、类等被实际使用了。这些标记可以是通过变量引用、函数调用等方式进行识别。

3. 剔除未使用的代码:根据标记结果,工具会将未被使用的代码从最终生成的文件中剔除掉。这些未使用的代码可能是整个模块、模块中的某些函数或类等。

4. 优化输出结果:在剔除未使用代码后,工具会对输出结果进行进一步优化。它可能会进行变量重命名、函数内联等操作,以进一步减少文件大小和提高执行效率。

Tree Shaking原理的核心在于静态分析和标记未使用代码。通过对模块依赖关系的分析,工具可以确定哪些代码是被实际使用的,哪些是未使用的。这种静态分析是在编译时进行的,因此可以在打包过程中进行优化,而不需要运行时的额外开销。

需要注意的是,Tree Shaking只能消除那些在编译时可以确定未使用的代码。对于动态导入、条件导入等情况,工具可能无法准确判断哪些代码会被使用。因此,在使用Tree Shaking时,开发者需要注意编写可静态分析的代码,以确保最终生成的文件能够得到有效优化。

由于是静态分析,所以我们在写代码的时候,需要注意自己的写法,简单来说,尽量的使用最小导入,比如你可以比较一下我们这里导入代码之后,打包的区别:

// 直接默认导入整个对象importutilfrom"./util.js";
constr=util.getRandomNum(1, 10)
console.log(r)
// 具名导入具体的函数import { getRandomNum } from"./util.js";
constr=getRandomNum(1, 10)
console.log(r)

总结

总结起来,Rollup通过解析模块依赖关系、进行Tree Shaking操作和合并模块代码等步骤,实现了高效而精简的模块打包功能。它是一个强大而灵活的工具,适用于各种规模和类型的JavaScript项目。

目录
相关文章
|
安全 算法 Oracle
「隐语小课」Blazing Fast PSI 协议解读
「隐语小课」Blazing Fast PSI 协议解读
1751 0
|
缓存 架构师 Java
入职阿里巴巴,成为年薪百万阿里P7高级架构师需要必备哪些技术栈
大家都知道,阿里P7高级技术专家,基本上是一线技术人能达到的最高职级,也是很多程序员追求的目标。达到 年入百万的P7 Java高级架构师级别,不仅要具备优秀的编程能力和系统设计能力,在技术视野和业务洞察力方面,也要有很深的积淀。
|
11月前
|
人工智能 安全 API
MCP协议的具体技术实现原理
MCP(Model Context Protocol)是由Anthropic提出的开放协议,旨在标准化大语言模型(LLM)与外部工具、数据源的交互方式。通过客户端-服务器架构与JSON-RPC通信,实现工具的动态发现、安全调用与灵活扩展,提升LLM的实用性与集成效率。
|
11月前
|
人工智能 自然语言处理 并行计算
Github 12k star ,Shap‑E 深度解析:秒生成 3D 模型,一文掌握应用与技巧
Shap-E 是 OpenAI 开源的创新工具,能将文本或图片秒级转换为高质量 3D 模型,支持 Mesh 与 NeRF 格式输出。具备快速生成、双模态输入、本地部署等优势,适用于游戏原型、3D 打印、内容创作等场景,GitHub 已获 12k+ 星标。
1068 0
|
11月前
|
人工智能 数据可视化 测试技术
AI时代的接口调试与文档生成:Apipost 与 Apifox 的表现对比
在AI技术驱动的数字化时代,软件开发日益复杂,团队协作与效率至关重要。接口调试与文档生成贯穿开发全流程,影响项目进度与质量。Apipost与Apifox作为主流工具,功能差异显著。本文从WebSocket调试、Socket.IO协议支持、GraphQL调试及AI能力等维度进行深度对比,分析两者在接口调试与文档生成方面的优劣,为开发团队选型提供参考依据,助力提升开发效率与协作水平。
519 2
AI时代的接口调试与文档生成:Apipost 与 Apifox 的表现对比
ts中interface和type的区别
ts中interface和type的区别
1431 61
|
人工智能 前端开发 程序员
通义灵码 AI 程序员与开发者结伴编程,全栈开发电商工程的前后端功能需求
当你又收到了项目新需求的时候,可以尝试下载并使用通义灵码,让通义灵码 AI 程序员跟你一起结伴编程,它具备多文件代码修改和工具使用的能力,可以与你结伴协同完成编码任务,如需求实现、缺陷修复、单元测试生成、批量代码修改等,成为你的左膀右臂。下面我们就跟AI程序员结伴编程完成前后端需求的开发吧!
1070 1
|
存储 人工智能 搜索推荐
整合长期记忆,AI实现自我进化,探索大模型这一可能性
本文探讨了通过整合长期记忆(LTM),AI模型能否实现自我进化,以提升处理新任务和适应环境的能力。LTM能帮助模型存储和利用长期信息,提高决策质量和服务个性化水平。文章还讨论了LTM整合的挑战及解决方案,以及如何借鉴人类记忆机制设计有效的LTM策略。[论文链接](https://arxiv.org/pdf/2410.15665)
906 17
|
缓存 前端开发 JavaScript
深入了解rollup(三)插件机制
Rollup 插件是一个对象,具有属性]、构建钩子 和 输出生成钩子 中的一个或多个,并遵循我们的约定。插件应作为一个导出一个函数的包进行发布,该函数可以使用插件特定的选项进行调用并返回此类对象。 插件允许你通过例如在打包之前进行转译代码或在node_modules文件夹中查找第三方模块来自定义 Rollup 的行为。
484 1