来源:Babel+corejs

babel

谈到babel,通常会想到“ES6转ES5”,但其实babel本身只转语法

babel在转换的过程中,会经历源代码→AST抽象语法树→转换语法树→生成ES5代码这些过程

然而ES6相较ES5,既有新语法,又有新特性:语法就是书写时遵守的格式;特性就是API

1
2
3
4
5
6
7
// 这些是语法,会被babel本身转换
const a = 114514
const fun = ()=>{}

// 这些是特性,不会被babel本身转换
new Promise()
Object.assign({})

可以看出,ES6新特性确实无法被babel转换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import babel from '@babel/core'
import presetEnv from '@babel/preset-env'
import fs from 'node:fs'

const code = fs.readFileSync('./index.js', 'utf-8')

const res = babel.transformSync(code, {
// 增加转换预设后才能真正转换
presets: [presetEnv], // es6转es5
})

console.log(res.code)
/** ->
* var a = 114514;
* var fun = function fun() {};
*
* new Promise();
* Object.assign({});
*/

corejs

只转换语法而不转换特性的话,低版本浏览器照样无法良好地运行代码,这时就需要corejs

corejs提供polyfill(垫片),会检测运行环境是否有该API,如果有则使用,没有则自己提供实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import babel from '@babel/core'
import presetEnv from '@babel/preset-env'
// import corejs from 'core-js'
import fs from 'node:fs'

const code = fs.readFileSync('./index.js', 'utf-8')

const res = babel.transformSync(code, {
// 增加转换预设后才能真正转换
presets: [[
presetEnv,
// 配置corejs
{
useBuiltIns: 'usage', // 按需引入新特性的实现
corejs: 3 // 版本
}
]], // es6转es5
})

console.log(res.code)
/** ->
* "use strict";
*
* require("core-js/modules/es.object.assign.js");
* require("core-js/modules/es.object.to-string.js");
* require("core-js/modules/es.promise.js");
*
* var a = 114514;
* var fun = function fun() {};
*
* new Promise();
* Object.assign({});
*/