什么是 Babel
Babel 是一个 JavaScript 编译器,用于将 ES6+ 的代码语法转换为向后兼容的语法,以便能够在当前版本和旧版本的浏览器中运行。
简单来说你可以用来它来干这 3 件事:
- 语法转换
- 通过 polyfill 的方式添加目标环境缺失的特性
- 源码转换(codemods),比如,jsx 转换为 js, ts 转换为 js。
基本原理
首先将源码转换成抽象语法树,然后将抽象语法树进行处理生成新的语法树,最后根据新的语法树生成 js 代码。
需要注意的是,babel 只会编译新标准引入的语法,例如,箭头函数,Class,ES Module 等,不会编译原生对象的新方法, 例如, Array.includes,Array.map,Array.reduce, 这些都是通过 polyfill 实现的。
plugins
babel 编译转换 js 语法的能力,正是通过配置插件实现的。配置合适的插件就能将特定的 js 语法转换成所需要的语法。比如:
perl
"plugins": ["@babelplugin-transform-arrow-functions"]
可以转换箭头函数语法。
但是 ES6+ 语法那么多,总不能每个语法都自己配置插件吧,幸运的是,babel 替我们预设了配置,来解决开发中常见的那些常见问题。
presets
Presets 是 babel 的预设配置,最好用的预设配置当属 @babel/preset-env,它不仅预配置了转换 ES6+ 代码语法的插件, 还能自动按需添加 polyfill。它真的,我哭死。
另外当我们编写 React 代码时,也是需要 babel 帮我们把 jsx 转换为 js。要满足这一需求,可以直接使用 @babel/prest-react
@babel/preset-env
-
配置兼容哪些浏览器来转换 js 语法
"browserslist": "> 0.25%, not dead"
表示仅包括浏览器市场份额超过 0.25% 的用户所需的 polyfill 和代码转换(忽略没有安全更新的浏览器,如 IE10 和 BlackBerry)
-
配置按需自动引入 polyfill:
"@babel/preset-env", { useBuiltIns: 'usage', corejs: "3"}
以上我们通过 @babel/preset-env 干了 babel 最核心的两件事,还剩最后一件事源码转换,下面就介绍 jsx 的源码转换。
@babel/preset-react
在编写 React 代码时,使用的是 jsx 语法,但是浏览器不认识这种语法,幸好 babel 提供了源码转换的预设配置 @babel/preset-react,能将 jsx 转换为 js。
以下是配置代码:
css
["@babel/preset-react", { runtime: "automatic" }]
目前的 babel7(7.23.5)的 runtime 默认是 classic,要设置为 automatic 才能兼容最新的 React17 和 React18, 否则会报错 React is not defined
优化
由于 babel 的一些公共方法,需要一些辅助函数,babel 要转换的每个 js 文件中都要引入一遍,文件一多势必会产生浪费,好在 babel 给我们提供了一个插件来解决这个问题,只需要像下面这样配置就好了
perl
"plugins": ["@babel/plugin-transform-runtime"]
配置这个插件也需要安装两个依赖包,安装方法如下,注意 @babel/runtime 要安装在生产依赖
sql
yarn add --dev @babel/plugin-transform-runtime
yarn add @babel/runtime
通过这个插件,辅助函数都是 @babel/runtime 的引用。
总结
babel 就干 3 件事,第一是转换语法,第二是添加polyfill,第三是转换源码。
转换语法,通过配置插件实现。
添加 polyfill,通过@babel/preset-env 自动按需引入,另外 @babel/preset-env 还配置了最新的 ES6+ 代码转换插件,相当于整合了语法转换和添加 polyfill,真是太棒了。
转换源码, 比如 jsx 转换 js ,通过配置 @babel/preset-react实现。
优化 babel 的辅助函数为单独的包,通过 @babel/plugin-transform-runtime 插件实现。