包阅导读总结
1.
关键词:TypeScript、隔离声明、JavaScript 生态系统、代码打包、定义文件
2.
总结:本文主要介绍了 TypeScript 5.5 推出的隔离声明功能,它极大地加快了 JavaScript 生态系统的发展,简化了代码打包和分发流程,大幅提升了定义文件生成速度,改变了共享代码的方式,目前 JSR 是首个利用此优势的注册表。
3.
主要内容:
– 隔离声明功能加快了 JavaScript 生态系统的发展
– 简化代码打包和分发流程
– 大幅提升类型定义文件生成速度
– 现状与问题
– 2024 年 npm 打包混乱,创建 npm 包挑战大
– 生成.d.ts 文件耗时的核心在于架构和类型推断
– 隔离声明的作用
– 让生成.d.ts 文件变得简单快速
– 改变了打包和发布流程
– 改变了声明包可用项的方式
– 实际应用
– 在 Deno 中已使用半年
– 可在多种包管理器中使用
– 对 npm 仍需后台生成打包文件中的定义文件
– 结论
– 隔离声明改变了发布规则,JSR 是首个利用此优势的注册表
思维导图:
文章地址:https://mp.weixin.qq.com/s/d-oMEhbjoNKZFl2qxMQrIA
文章来源:mp.weixin.qq.com
作者:飘飘
发布时间:2024/7/18 0:02
语言:中文
总字数:2920字
预计阅读时间:12分钟
评分:83分
标签:TypeScript,JavaScript,打包工具,类型定义,npm
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com
前言
TypeScript 5.5 推出的隔离声明(isolatedDeclaration)功能极大地加快了 JavaScript 生态系统的发展,通过简化代码打包和分发流程,以及大幅提升类型定义文件(.d.ts
)的生成速度,使得开发者之间共享代码变得更加高效和便捷。今日前端早读课文章由 @飘飘翻译分享。
正文从这开始~~
简而言之:TypeScript 的新型隔离声明功能是让开发人员之间共享代码的一大变革。它大大简化了打包代码以供使用的过程,同时将创建类型定义文件的时间从几分钟,有时甚至几小时缩短到一秒钟以内。
许多开发者可能不知道,TypeScript 5.5 中新引入的一项功能比想象中重要得多。它彻底改变了我们打包和分发 JavaScript 代码的方式。你不再需要手动创建*.d.ts
文件,只需调用 tsc 编译器即可。在 MacOS 上进行的 “查看源文件”(即按 ctrl+click 或 cmd+click 操作)现在真的可以使用了,它会直接带你到 TypeScript 源代码,而不是*.d.ts
文件或一些编译后的 JavaScript 代码。此外,它使发布包的速度比以往任何时候都快。
【第2877期】加快JavaScript生态系统的速度 – eslint
它是如何做到这一点的呢?让我们回过头来评估一下 2024 年 JavaScript 代码打包的现状。
2024 年的 npm 打包工作一团糟
说实话,这真是一团糟。没必要粉饰太平。我的一位朋友想把他的第一个库发布到 npm 上,但他很快就放弃了,因为他意识到这需要付出大量的工作和专业知识。你必须关心 CommonJS 和 ESM 的问题,还要对一系列设置进行微调,以使*.d.ts
文件能够正常工作,而且问题还有很多。最后,他放弃了这个任务,而是直接在项目之间复制粘贴文件。这比处理所有打包问题要省事得多。
打包代码应该像上传文件一样简单。打包和共享代码应该如此简单,以至于每个开发人员,无论其经验水平如何,都能做到这一点。
即使对于经验丰富的开发人员来说,创建可在各种环境中使用的 npm 包也是一项相当大的挑战。Redux 团队的马克 – 埃里克森(Mark Erikson)写了一篇长达多页的博文,讲述了他创建 npm 包的经历。关键是,将代码打包并在开发人员之间共享应该很容易。开发人员不应该需要阅读十几篇博客文章,成为所有这些工具内部机制的专家才能共享代码。它应该 “只需工作即可”。
出现了各种 CLI 工具来帮助解决这个问题,但这只会增加另一个摩擦点。你有工具 A,可以解决部分问题,然后你有工具 B,只处理问题的另一部分,等等。很快,你就得时刻关注哪个工具才是正确的选择,直到它被另一个工具所取代。这很糟糕。
那么,我们该如何解决这些问题呢?
生成.d.ts
文件为何耗费大量时间
问题的核心在于架构。我们只会打包构建好的构件,包括编译后的 JS 文件和相关的.d.ts
文件。如果能将原始的 TypeScript 源文件打包在一起就更好了,但目前 JavaScript 生态系统中几乎没有工具能支持这种做法。我们的工具普遍认为 node_modules 文件夹中的任何内容都不需要编译,这种假设已经深入人心。如果使用 TypeScript,则将源文件打包而不是.d.ts
文件,在性能上也会有所退化。
解析.d.ts
文件比解析普通的.ts
文件要快得多,因为它们只包含类型检查所需的部分。一个.d.ts
文件不包含函数体或其他内容,仅包含用于消费模块所需的类型定义。
// Input: add.ts
const SOME_NUMBER = 10;
export function quickMath(a: number, b: number) {
return a + b + SOME_NUMBER;
}
// Output: add.d.ts, contains only the bits needed for type checking
export function quickMath(a: number, b: number): number;
通常情况下,函数的返回类型并不确定。TypeScript 编译器必须先遍历并检查整个函数体,然后才能推断出返回类型。就性能而言,推断过程的代价非常高,尤其是对于复杂的函数。因此,创建.d.ts
文件的目的是摆脱所有推理,这样 TypeScript 编译器只需要读取这些文件,而不需要做额外的工作。类型推断是创建.d.ts
文件耗时如此之长的主要原因。因为这个过程耗时很长,所以我们尽量在创建 npm 包时提前完成。
使用隔离声明时,所有这些都会发生变化。
进入打包新时代
隔离声明背后的理念是,让 TypeScript 编译器以外的工具从 TypeScript 源代码中生成.d.ts
文件变得微不足道。它通过要求对导出的函数和其他元素显式指定返回类型来实现这一点。不过别担心,如果一个类型的推理难以理解,TypeScript 语言服务器会提供一个方便的功能,为你推断缺失的类型。
通过将这个过程简化为单纯的语法解析过程,创建.d.ts
所需的时间已接近 0 秒。借助一个专门基于 Rust 的解析器,即使是大型项目,也能在瞬间完成,因为现在可以并行执行此工作。速度快到你根本不会注意到。如果没有隔离声明,你总是需要调用 tsc 编译器并运行完整的类型检查。
由于生成定义文件的成本几乎为零,因此在需要时可以快速地即时生成。我们可以将发布流程颠倒过来:不再需要事先构建和发布.d.ts
文件,而是可以直接上传未经修改的 TypeScript 源代码,并在安装包时自动生成定义文件。.d.ts
文件不会在发布软件包时生成,而是在安装软件包时生成。
这也改变了你声明包可用项的方式。以前使用 npm 时,你必须引用几个构建工件才能实现这一点。
// package.json
{
"name": "@my-scope/my-package",
"version": "1.0.0",
"type": "module",
"exports": {
".": {
"types": "./dist/types/index.d.ts",
"import": "./dist/index.js"
},
"./foo": {
"types": "./dist/types/foo.d.ts",
"import": "./dist/foo.js"
}
}
}
基于隔离声明的系统要简单得多:直接引用源文件即可。
// jsr.json
{
"name": "@my-scope/my-package",
"version": "1.0.0",
"exports": {
".": "./src/index.ts",
"./foo": "./src/foo.ts"
}
}
将软件包中的入口指向实际的源文件感觉更加自然,因为它让你不再担心打包产生的文件。
在生产中使用
当然,理论上谈论这些事情是很好的,但在生产中会有什么感觉呢?隔离声明背后的核心理念已经在 TypeScript 问题跟踪器中被多次提出,但需要一些时间和许多聪明的头脑才能最终确定。在 Deno(免责声明:我为 Deno 工作),我们从一开始就密切关注这一过程,并开始开发我们自己的基于 rust 的版本。从 2023 年 12 月初开始,我们在这篇文章中谈到的系统正是 Deno 的打包工作方式。到目前为止,每个 Deno 用户在生产中使用它已经超过半年了。
在编辑器中,诸如 “跳转到源代码” 的功能是原生的,它实际上会将您带到源代码文件中,而不是随机的某个定义文件。
我们意识到拥有这样一个系统是有用的,并让它对所有人都可用,而不仅仅是 Deno 用户。你可以在 npm 、 yarn 、 pnpm 甚至 bun 中使用它。JSR 注册表通过实现 npm 安装包的协议来实现这一点,在与这些软件包管理器通讯时,它仅作为另一个 npm 注册表。从包管理器的角度来看,与您可能已经在公司中使用的任何其他私有 npm 注册表进行通信并没有什么不同。
因为 npm 客户端没有在运行时生成定义文件的系统,所以我们在后台的发布过程中为 npm 打包文件生成这些文件。因此,npm 打包文件中包含了您已经从其他项目中熟悉的标准转译后的.js
文件。整个 npm 生态系统都是基于分发.js
文件的,改变这一点会破坏整个生态系统。因此,这里的要点不是仅将 TypeScript 发布到 npm 上。
但是,如果你使用的运行时可以原生运行 TypeScript,并且使用的注册表也可以分发原始的 TypeScript 源,那么隔离的声明就是一个改变游戏规则的因素。
结论
隔离声明彻底改变了发布的游戏规则。它使生成定义文件的过程近乎零成本,为即时生成定义文件打开了大门。这大大简化了发布过程,只需上传源文件即可,速度大大加快。目前,JSR 是第一个也是唯一一个利用这一优势的注册表,它可以与任何包管理器一起在任何运行时中使用。一言以蔽之,JSR 的目标用户是那些觉得人生苦短,无法处理所有打包问题,只想共享代码的人。快来试试吧
关于本文
译者:@飘飘
作者:@marvinhagemeist
原文:https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-10/
这期前端早读课
对你有帮助,帮”赞“一下,
期待下一期,帮”在看” 一下 。