ECMAScript 发展困境
JavaScript这门语言受限于历史因素,有许多问题,其中一个就是新的语言特性始终无法在浏览器中得到全面支持与应用。
如果你要写一个支持绝大多数浏览器的网页,最好的选择可能就是ES5了,但你要知道ES5之后,JavaScript也一直在不停的更新,其中最重要的一个版本是ES 6,而到今年2022年,已经是ES 2022(ES13)了
和其它语言不同,JavaScript是要在浏览器中运行,这就决定了你在使用JS时不得不考虑浏览器的支持情况。
什么是Babel
Babel 是一个 JavaScript 编译器。主要用于将采用 ES 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。比如:
- 语法转换(ES6转ES5,转换 JSX 语法)
- 通过 Polyfill 方式在目标环境中添加缺失的特性 (通过引入第三方 polyfill 模块,例如 core-js)
- 由于 Babel 支持 Source map,因此你可以轻松调试编译后的代码。
Babel原理
babel的转移过程分为三个阶段,这三个步骤分别是:
- 解析(parse):将代码解析生成抽象语法树(AST),先词法分析再语法分析的过程,最终转为AST。 使用 @babel/parser 解析代码,对不同词法添加不同type。
- 转换(Transform):对于AST进行变换的一些列的操作,babel接收得到的AST并通过babel(遍历)的相关插件
babel-traverse
对其进行遍历,在此过程中进行添加,更新以及移除等操作。 - 生成(Generate):将变换后的AST再转换为JS代码,转换成字符串形式的代码,同时还会创建源码映射(source maps),使用到的模块是
babel-generator
。
什么是Polyfill
polyfill 指的是“用于实现浏览器不支持原生功能的代码”。
比如,现代浏览器应该支持 fetch
函数,对于不支持的浏览器,网页中引入对应 fetch
的 polyfill 后,这个 polyfill 就给全局的window
对象上增加一个fetch
函数,让这个网页中的 JavaScript 可以直接使用 fetch
函数了,就好像浏览器本来就支持 fetch
一样。
Babel中的Polyfill作用
Babel 包含一个 core-js 的 polyfill。默认情况下babel可以将箭头函数,class等语法转换为ES5兼容的形式,但是却不能转换Map,Set,Promise等新的全局对象和一些新的API,这时候就需要使用polyfill去模拟这些新特性。
新的API有Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign,Array.from,Array.prototype.includes)都不会转码。
使用babel-polyfill,可以为当前环境提供相应API的垫片。
什么是SWC
SWC(Speedy Web Compiler
)是用 Rust 编写的超快 TypeScript / JavaScript 编译器。是一个社区驱动的项目。
SWC 的编译旨在支持所有 ECMAScript 功能。SWC CLI 旨在替代 Babel。可以说是更快的babel。
SWC相比于Babel的优势
Babel是JavaScript写的,JavaScript就是有点慢。而swc也提供了对 webpack 良好支持,所以使用webpack + swc搭配没有任何问题。
什么是esbuild
esbuild是由go语言写的。而最近比较流行的Vite工具,它就是使用的esbuild,所以它非常快。
ESbuild 是一个类似webpack构建工具。它的构建速度是 webpack 的几十倍。
- esbuild是新开一个进程,然后多线程并行,充分发挥多核优势
- go是纯机器码,肯定要比JIT快
- 不使用 AST,优化了构建流程。
使用 esbuild 去做一些代码的 transform (代替 babel-loader)。
SWC与esbuild
如果是这样,我们都很容易会去思考一个问题,如果JavaScript能写一个转换器,为什么不用一些更高性能的语言来写一个类似的转换器呢?
好想法,这也是为什么会有swc与esbuild 出现的原因。babel是开创性的,但这不表示我们不能有新的东西取代它,技术就是如此,新的取代旧的,这是永恒不变的趋势。
本文固定连接:https://code.zuifengyun.com/2022/09/3055.html,转载须征得作者授权。