前言
之前没有自己搭建过前端项目,在熟悉已有项目的过程中看到 package.json里关于 babel 的依赖就有这么多,他们分别都是干嘛的呢?每次搭建项目都需要这些依赖吗?
文末会列出各种配置所需要安装的库和配置文件。如有不对,希望指正。
babel 的作用
babel 为了解决 js 在不同浏览器的兼容问题,主要是语法和 API 这两个兼容问题。
plugin 与 preset
babel 将很多的语法转换交给了一个个 plugin 处理,例如 @babel/plugin-transform-arrow-functions 这个插件可以转换箭头函数语法,但是为了不需要手动一个个添加,所以提供了@babel/preset-env,可以理解成 preset 包含了很多 plugin 。所以只需要配置一个 preset 就可以转换成浏览器支持的语法了。
core-js + regenerator-runtime = @babel/polyfill
要使用浏览器不支持的 API 可以自己写一些模拟函数,这些模拟函数叫做 polyfill。要使用Promise 或 WeakMap 等新内置函数、Array.from 或 Object.assign 等静态方法、Array.prototype.includes 等实例方法需要 core-js@3 这个库。要使用生成器函数(function* )需要 regenerator-runtime 这个库。
为了使用这些函数,需要在 babel 的配置文件(见文末)配置 @babel/preset-env。其中有一个参数是 useBuiltIns ,它有三个值:1,默认是 false,false 的作用是不使用 polyfill;2,uasge 的作用是自动且按需引入用到的 polyfill;3,entry 的作用是全量引入 polyfill,需要要入口文件手动引入 import "core-js";、 import 'regenerator-runtime/runtime';。
@babel/polyfill 这个库已经不推荐使用了,简单提一下。它实际上就是 core-js@2 + regenerator-runtime,core-js@2 也不推荐使用,现在单独安装和引用 core-js@3 和 regenerator-runtime 就行。
@babel/runtime 抽离公共辅助函数
babel 生成的代码会有一些辅助函数,例如 _createClass 函数,这些函数在每个文件里面都会重复生成,所以可以把重复函数抽取出来,然后每个文件引用即可,这样就可以减少生成的代码体积。这些函数被抽取到 @babel/runtime 这个库里。为了自动使用 @babel/runtime 里的函数,还需要 @babel/plugin-transform-runtime 插件。
抽取前如下:
抽取后如下:
可以看到 regenerator 使用的是 @babel/runtime/regenerator,所以如果用了 @babel/runtime 应该就不需要自己手动单独安装 regenerator-runtime 。
@babel/runtime-corejs3 避免污染全局环境。
使用 core-js@3 来 polyfill,会全局引入缺少的 API,例如 require("core-js/modules/es.promise.js")。有时候开发工具库,希望避免 polyfill 污染全局变量。这时候可以不使用 core-js@3 来 polyfill,转而使用 @babel/runtime-corejs3,@babel/runtime-corejs3 相当于 @babel/runtime + 不污染环境的 core-js@3。
使用 @babel/runtime-corejs3 后如下,可以看到 _promise 不是一个全局变量:
总结
根据以上的理解,其实一般有两种配置,一种是 @babel/preset-env + @babel/runtime + core-js@3,普通的项目不怕污染全局环境可以用这个配置;另外一种是 @babel/preset-env + @babel/runtime-corejs3,开发工具类库为了不污染全局环境可以用这个配置。
配置一: @babel/preset-env + @babel/runtime + core-js@3
安装脚本:
npm install --save-dev @babel/cli @babel/core @babel/preset-env @babel/plugin-transform-runtime
npm install --save @babel/runtime core-js@3
babel.config.json 配置文件
{
"presets": [
[
"@babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3
}
]
],
"plugins": [
["@babel/plugin-transform-runtime"]
]
}
配置二: @babel/preset-env + @babel/runtime-corejs3
安装脚本:
npm install --save-dev @babel/cli @babel/core @babel/preset-env @babel/plugin-transform-runtime
npm install --save @babel/runtime-corejs3
babel.config.json 配置文件
{
"presets": [
[
"@babel/preset-env"
]
],
"plugins": [
[
"@babel/plugin-transform-runtime", {
"corejs": 3
}
]
]
}
vue-cli 如何配置 babel?
先来看看依赖文件 @vue/babel-preset-app/package.json
babel 的配置是通过代码生成的 @vue/babel-preset-app/index.js
可以看到 vue-cli 生成的项目是类似于配置一的。