Babel 入门

Babel 与 Polyfill 的关系和区别
Babel 默认只转换新的 js 句法(syntax),而不转换新的 API,例如箭头函数等
Polyfill 用于实现浏览器并不支持的原生 API 的代码,如新增的方法等

Babel

Babel 的安装,配置

创建 babel.config.js 文件,内容如下

babel.config.js 是 Babel 执行时会默认在当前目录寻找的 Babel 配置文件,除了 babel.config.js,我们也可以选择用.babelrc 或.babelrc.js 这两种配置文件

module.exports = {
presets: ["@babel/env"]
}

安装如下包

npm i -D @babel/cli @babel/core @babel/preset-env
  • @babel/cli 是 Babel 命令行转码工具,如果我们使用命令行进行 Babel 转码就需要安装它。
  • @babel/cli 依赖 @babel/core,因此也需要安装 @babel/core 这个 Babel 核心 npm 包。
  • @babel/preset-env 这个 npm 包提供了 ES6 转换 ES5 的语法转换规则,我们在 Babel 配置文件里指定使用它。如果不使用的话,也可以完成转码,但转码后的代码仍然是 ES6 的,相当于没有转码。

创建 index.js 文件,如下

const fn = (num) => num + 1
new Promise(() => {})

执行命令

npx babel index.js -o output.js

输出结果为

"use strict";

var fn = function fn(num) {
return num + 1;
};

new Promise(() => {});

可以看到,ES6 的箭头函数语法转换成了 ES5 的函数定义语法,但是并没有对 ES6 的 Promise 进行转换。因为 Babel 默认只转换新的 js 语法(箭头函数,解构…),而不转换新的 API。新的 API 分类两类,一类是 Promise、Map、Symbol、Proxy、Iterator 等全局对象及其对象自身的方法,例如 Object.assign,Promise.resolve;另一类是新的实例方法,例如数组实例方法 [1, 2, 3].find ((item) => item < 2)

polyfill

安装

npm install --save @babel/polyfill

在 index.js 中引入 import '@babel/polyfill'

执行命令

npx babel index.js -o output.js

输出结果

"use strict";

require("@babel/polyfill");

var fn = function fn(num) {
return num + 1;
};

new Promise(function () {});

输出结果中 require("@babel/polyfill");

import 被编译成了 require,如果想要编译出来的模块引入规范还是 import,则可以在 preset-env 的配置项中添加”modules”: false 即可

有时候我们项目里并没有用到那么多的新增 API,但是 @babel/polyfill 会把所有浏览器环境的的 polyfill 都引入,整个包的体积就会很大,我们想要对目标环境按需引入相应的 polyfill 应该怎么办呢,这个时候我们就可以使用 preset-env 的配置项中的 useBuiltIns 属性来按需引入 polyfill。

module.exports = {
presets: [
[
"@babel/preset-env", {
"modules": false, // 用来设置是否把ES6的模块化语法改成其它模块化语法
"useBuiltIns": "usage",
}
]
]
}

使用 useBuiltIns:”usage” 后,Babel 除了会考虑目标环境缺失的 API 模块,同时考虑我们项目代码里使用到的 ES6 特性,且不需要在项目入口处手动引入 polyfill

import "core-js/modules/es6.object.to-string.js";
import "core-js/modules/es6.promise.js";

var fn = function fn(num) {
return num + 1;
};

new Promise(function () {});

可以看到 多了 import "core-js/... 的引用,因为 @babel/polyfil 是由 core-js2 和 regenerator-runtime 组成的一个集成包,
Babel 7.4.0 之后已经弃用了 @babel/polyfill,所以 core-js 官方现在推荐我们使用 polyfill 的时候直接引入 core-js 和 regenerator-runtime/runtime 这两个包完全取代 @babel/polyfil

core-js
babel-polyfill