当前位置: 首页 > 科技观察

2022年,BabelvsTypeScript,谁更适合代码编译_0

时间:2023-03-13 13:00:37 科技观察

现代Web应用中,为了让代码在生产环境中高性能运行,往往需要对源代码进行编译打包,死代码删除、代码转换等处理。Babel和Typescript是当今最常用的两种编译器,本文重点介绍两者之间的区别,以帮助您为项目选择最佳工具。介绍BabelBabel是一个JS编译器,它将现代ES6+语法和特性转换为向后兼容的语法,可以在当前和旧浏览器或其他环境上运行。TypeScriptTS具备语法转换、polyfill、源代码转换等能力,是目前最常用的编程语言之一。它是带有类型系统的JS,可以帮助避免开发过程中的一些错误。TS有自己的编译器,可以将.ts文件转换成.js文件,然后在任何可以运行JS的环境中运行,比如浏览器、Node.js等。两者的比较虽然都是编译器,但是还是有一些区别的。Babel不能做类型检查TS可以在编译时对代码进行类型检查,Babel不支持类型检查。您可以使用tsc--noEmit单独执行TS类型检查。TS不能自动polyfill。Babel和TS都只是编译器。真正完成APIpolyfill的是core-js。core-js是一套模块化的JS标准库,提供了polyfill的核心实现。Babel的@babel/polyfill模块包括core-js和regenerator-runtime来模拟完整的ES2015+环境。所以可以说Babel自带了polyfill。regenerator-runtime是generator和async/await的运行时依赖项。而TS只能通过tsconfig的target控制编译成ECMAScript版本对应的语法。比如const/let改成var,箭头函数改成function,async+await改成Promise。那么这些就不介绍内置对象的扩展了。比如你要运行的浏览器不支持Promise,编译后不会带来完整的Promise。polyfill,想要polyfill,还是得配合core-js。Babel扩展性更强Babel是自定义代码转换的最佳选择,社区生态丰富,有各种插件可以优化你的代码。而且TS只支持自己的TransformerAPI,生态远不如Babel插件,知道的人少,能力也差。装饰器(Decorator)区别随着TS和ES6引入类,装饰器提案proposal-decorators[1]诞生了,也就是我们最熟悉的老朋友了。但是这个decorator不是那个decorator,提案时隔多年已经到了第三个版本,还停留在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字段分别支持三个版本的proposals:"2021-12""2018-09"(default)"legacy"Babel默认编译根据第二个版本。如果要和TS编译行为保持一致(即第一个版本),需要传入"version":"legacy"。Babel支持更多的语言特性。从上面的装饰器例子可以看出,TS只支持stage-3以上的语言特性,不支持还处于draft阶段的特性。并且Babel的preset-env支持所有标准特性,还可以通过各种@babel/plugin-proposal-插件支持更多尚未进入标准的特性。两者的编译速度相当。在性能方面,两者并没有太大的区别。说到这里你可能会有疑惑:“Babel少了类型检查这一步,所以编译速度应该比TS快。”根据swc-node[2]文档的benchmark可以看到,在关闭类型检查的情况下,TS的编译速度比Babel要快。esbuildx510ops/sec±1.28%(88次运行采样)@swc-node/corex438ops/sec±1.00%(88次运行采样)typescriptx28.83ops/sec±10.20%(52次运行采样)babelx24.21ops/sec±10.66%(46runssampled)转换rxjs/AjaxObservable.tsbenchmark基准套件:最快的是esbuild也可以使用第三方插件fork-ts-checker-webpack-plugin[3]来加速上了类型检查进程(放到一个单独的进程中),所以两者的整体性能其实相差不大。Babel产品比较小,因为TS不能自动polyfill,而借助core-js无法实现按需polyfill。并配置Babel的@babel/preset-env插件:useBuiltIns:"usage"添加目标浏览器targets:根据编译目标和项目的API用例准确添加polyfills,这将大大减少包的大小。使用useBuiltIns:"usage"在全局添加一个polyfill,会污染全局环境。您可以使用@babel/plugin-transform-runtime插件为库代码提供沙箱环境,将polyfills变成模块化导入,在代码重用的同时避免全局污染。小结综上所述,两者都有自己的编译处理方式。总的来说,Babel唯一的缺点就是没有类型检查,但是可以使用tsc--noEmit来单独检查类型。所以,如果你的项目:已经有Babel和TypeScript,最好使用Babel编译代码,使用TS进行类型检查并生成.d.ts文件。TS文档[4]中也推荐这种方式,但如果构建输出文件与源码差别不大,可以直接使用TS编译。只有TypeScript才能维持现状。如果以后需要Babel提供的能力,可以用Babel编译TS编译输出的JS,或者直接用Babel编译TS文件。只有Babel推荐使用TypeScript逐步改造项目,保证项目的前端质量。参考https://blog.bitsrc.io/babel-vs-typescript-in-2022-b8e859a9fefchttps://ts.xcatliu.com/https://jishuin.proginn.com/p/763bfbd3ba87https://jishuin。proginn.com/p/763bfbd5eecfhttps://juejin.cn/post/6968636129239105549https://blog.logrocket.com/babel-vs-typescript/https://www.typescriptlang.org/docs/handbook/babel-with-typescript.html#babel-vs-tsc-for-typescripthttps://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-插件[4]TS文档:https://www.typescriptlang.org/docs/handbook/babel-with-typescript.html