前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2022 年,Babel vs TypeScript,谁更适合代码编译【补充参考文献】

2022 年,Babel vs TypeScript,谁更适合代码编译【补充参考文献】

作者头像
Leecason
发布2022-07-13 14:25:14
6210
发布2022-07-13 14:25:14
举报
文章被收录于专栏:小李的前端小屋

由于前一篇文末遗漏了「参考」,被好心小伙伴指出,今天重发一版补上。谢谢大家❤️~

在现代 Web 应用中,为了让代码能在生产环境高性能的运营,源代码往往需要被编译打包,进行死码删除,代码转换等处理。

Babel 和 Typescript 是目前最常用的两个编译器,本文主要讨论两者的区别,帮助你为项目选择最佳工具。

介绍

Babel

Babel 是一个 JS 编译器,能将现代 ES6+ 语法和特性转换为向后兼容语法,以便能够运行在当前和旧版本的浏览器或其他环境中。拥有语法转换,Polyfill,源码转换等能力,

TypeScript

TS 是目前最常用的编程语言之一,是加了类型系统的 JS,能够帮助在开发时规避一些错误。

TS 有自己的编译器,可将 .ts 文件转换为 .js 文件,然后运行在浏览器、Node.js 等任何能运行 JS 的环境中。

两者对比

虽然同为编译器,但也有一些区别。

Babel 无法做到类型检查

TS 在编译时可以对代码进行类型检查,而 Babel 不支持类型检查。

可以使用 tsc -- noEmit 单独进行 TS 类型检查

TS 无法自动 polyfill

Babel 和 TS 两者都只是编译器,真正完成 API polyfill 的是 core-js

core-js 是一套模块化的 JS 标准库,提供了 polyfill 的核心实现。

Babel 的 @babel/polyfill 模块包含了 core-jsregenerator-runtime 来模拟完整的 ES2015+ 环境。因此可以说 Babel 自带了 polyfill。

regenerator-runtimegenerator 以及 async/await 的运行时依赖。

而 TS 只能通过 tsconfigtarget 控制编译为对应 ECMAScript 版本的语法。比如 const/let 变 var,箭头函数变 function,async+await 变 Promise.then 这些,不会引入内置对象的扩展,比如你要运行的浏览器不支持 Promise,编译后也不会带一个完整的 Promise polyfill,想 polyfill 还是得配合 core-js

Babel 扩展性更强

Babel 是自定义代码转换的不二之选,而且社区生态丰富,有各种各样的插件可以优化你的代码。

而 TS 只支持自己的 Transformer API,生态远远比不上 Babel 插件,知道的人也比较少,能力也更少。

装饰器(Decorator)差异

随着 TS 和 ES6 里引入了类,装饰器提案 proposal-decorators[1] 诞生了,是我们最熟悉的老朋友。但是此装饰器非彼装饰器,历时多年来该提案已经走到了第三版,仍然卡在 stage-2。

首先我们需要知道,JS 与 TS 中的装饰器不是一回事,JS 中的装饰器目前依然停留在 stage-2 阶段,并且目前版本的草案与 TS 中的实现差异相当之大(TS 是基于第一版,JS 目前已经第三版了),所以二者最终的装饰器实现必然有非常大的差异。

其次,装饰器不是 TS 所提供的特性(如类型、接口),而是 TS 实现的 ECMAScript 提案(就像类的私有成员一样)。TS 实际上只会对 stage-3 以上的语言特性提供支持,但因为一些原因,当 TS 引入装饰器时,JS 中的装饰器依然处于 stage-1 阶段。TS 的装饰器其实是 JS 装饰器提案的第一版

Babel 编译装饰器需要使用 @babel/plugin-proposal-decorators 插件,通过 version 字段分别支持三版提案:

  • "2021-12"
  • "2018-09"(默认)
  • "legacy"

Babel 默认按第二版进行编译,如果要与 TS 编译行为一致(也就是第一版),需要传入 "version": "legacy"

Babel 支持更多语言特性

从上面装饰器的例子还可以看出,TS 只会对 stage-3 以上的语言特性提供支持,不支持还在草案阶段的特性。

而 Babel 的 preset-env 支持所有标准特性,还能通过各种 @babel/plugin-proposal-<语言特性> 插件来支持更多还未进入标准的特性。

两者编译速度相当

在性能上,两者差别不大。这里大家可能会有疑问:“Babel 少了类型检查的步骤,编译速度应该会比 TS 快才对啊”。

根据 swc-node[2] 文档的 benchmark 我们可以看到,在关闭类型检查的情况下,TS 的编译速度是比 Babel 快的

代码语言:javascript
复制
esbuild x 510 ops/sec ±1.28% (88 runs sampled)
@swc-node/core x 438 ops/sec ±1.00% (88 runs sampled)
typescript x 28.83 ops/sec ±10.20% (52 runs sampled)
babel x 24.21 ops/sec ±10.66% (46 runs sampled)
Transform rxjs/AjaxObservable.ts benchmark bench suite: Fastest is esbuild

而且还可以借助第三方插件 fork-ts-checker-webpack-plugin[3] 来提速类型检查过程(放到单独的进程中),所以两者的整体性能其实相差不大。

Babel 产物体积更小

因为 TS 无法自动 polyfill,借助了 core-js 也无法做到按需 polyfill。

而配置 Babel 的 @babel/preset-env 插件:

  • useBuiltIns: "usage"
  • 添加目标浏览器 targets: <需要兼容的浏览器>

可以根据编译目标和项目的 API 使用情况来精准添加 polyfill,这会大大降低包的体积。

使用 useBuiltIns: "usage" 会在全局添加 polyfill,这会污染全局环境。可以使用 @babel/plugin-transform-runtime 插件为库的代码提供一个沙盒环境,把 polyfill 变成模块化的引入,代码重用的同时避免全局污染。

总结

综上,两者都有各自的编译处理方式,整体看下来,Babel 唯一的缺点就是没有类型检查,但可以使用 tsc --noEmit 单独检查类型。

因此,如果项目中:

  • 已有 Babel 和 TypeScript,最好使用 Babel 编译代码,使用 TS 进行类型检查和生成 .d.ts 文件

TS 文档[4]中也更推荐这种方式,但如果构建输出文件和源码差别不大的话,可直接使用 TS 编译。

  • 只有 TypeScript,可以保持现状,将来如果需要 Babel 提供的能力,可以将 TS 编译输出的 JS 再使用 Babel 编译,或者直接使用 Babel 编译 TS 文件
  • 只有 Babel,推荐使用 TypeScript 对项目进行渐进式改造,保证项目前端质量。

参考

  • https://blog.bitsrc.io/babel-vs-typescript-in-2022-b8e859a9fefc
  • https://ts.xcatliu.com/
  • https://jishuin.proginn.com/p/763bfbd3ba87
  • https://jishuin.proginn.com/p/763bfbd5eecf
  • https://juejin.cn/post/6968636129239105549
  • https://blog.logrocket.com/babel-vs-typescript/
  • https://www.typescriptlang.org/docs/handbook/babel-with-typescript.html#babel-vs-tsc-for-typescript
  • https://www.zhihu.com/question/322722786

谢谢支持❤️

如果觉得不错,帮我点个「赞」和「在看」吧,谢谢各位大佬~

参考资料

[1]

proposal-decorators: https://github.com/tc39/proposal-decorators

[2]

swc-node: https://github.com/Brooooooklyn/swc-node#benchmark

[3]

fork-ts-checker-webpack-plugin: https://github.com/TypeStrong/fork-ts-checker-webpack-plugin

[4]

TS 文档: https://www.typescriptlang.org/docs/handbook/babel-with-typescript.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小李的前端小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
    • Babel
      • TypeScript
      • 两者对比
        • Babel 无法做到类型检查
          • TS 无法自动 polyfill
            • Babel 扩展性更强
              • 装饰器(Decorator)差异
                • Babel 支持更多语言特性
                  • 两者编译速度相当
                    • Babel 产物体积更小
                    • 总结
                    • 参考
                    • 谢谢支持❤️
                      • 参考资料
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档