开始使用 Babel
Babel工具链中有不少的工具,无论你是在项目中通过简单配置 Babel 让其能够“编译”JavaScript 代码也好,还是开发一个工具,把 Babel 集成到你的工具中也好,这些工具都能够让你轻松的使用 Babel。
课前准备
下面我们用代码展示下,如何使用 Babel把 ES2015+ 的代码,编译成可以在任何浏览器中运行的代码。 为此,我创建了一个纯净的模版项目 ,你可以直接使用,从而避免了自己去新建项目,手动创建一些无关紧要的文件夹等等。
- 安装degit
pnpm i degit -g- 创建新目录存放模板
mkdir your-project-dir- clone 项目模版
degit tolerious/simple-babel-template注意
别忘记先创建一个空的目录,然后在该目录中运行上述degit命令,执行结束后,在进入文件夹运行如下命令:
pnpm i实操
安装依赖
pnpm add --save-dev @babel/core @babel/cli @babel/preset-env创建Babel 配置文件babel.config.js,并添加如下内容:
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"chrome": "43"
},
"useBuiltIns": "usage",
"corejs": "3.6.5"
}
]
]
}创建测试javascript文件
// Babel 演示代码
console.log('Hello from Babel demo!');
// 示例:使用 ES6+ 语法
const greeting = (name) => {
return `Welcome to Babel, ${name}!`;
};在这个例子中,我们使用了一个箭头函数。 在终端中运行
./node_modules/.bin/babel index.js --out-dir lib我们将在lib目录中看到生成的一个名为index.js的文件,内容如下:
"use strict";
// Babel 演示代码
console.log('Hello from Babel demo!');
// 示例:使用 ES6+ 语法
var greeting = function greeting(name) {
return `Welcome to Babel, ${name}!`;
};我们可以很容易的看到这两个文件的差异所在,
- 在第一行开启了严格模式
- 箭头函数被编译成了普通的函数 下面就这两个不同的点做一些分析,后续在做代码测试的时候,在对比编译前后的文件时发现有不一致的地方,都可以用类似的方法进行分析,就可以知道为什么有的代码被编译了,有的代码却没有被编译了。
严格模式
我不禁产生了疑问,我的源文件也没开启严格模式啊,为啥编译出来的文件开启了严格模式,是不是经过Babel编译的js文件都会变成严格模式呢?下面我们就来一探究竟。
我们回头看看我们的Babel配置文件,我们使用了最基础的配置,最基础,也就意味着,有一些配置选项时默认的,问题就出现在了这里。 在Babel中我们有一个配置选项叫做sourceType,它与presets选项平级。默认值为module,意思就是
使用 ECMAScript 模块语法解析文件。文件自动采用严格模式,且允许使用 import/export 语句。
你可以尝试在配置文件中把它改成其它值,比如commonjs, 那么,你就可以看到在编译好的文件中,严格模式就没了。具体的解释说明可以参考这里。
{
"sourceType": "commonjs",
"presets": [
[
"@babel/preset-env",
{
"targets": {
"chrome": "43"
},
"useBuiltIns": "usage",
"corejs": "3.6.5"
}
]
]
}编译箭头函数
我们在源文件中使用了箭头函数,在编译过后的文件中,箭头函数被编译成了普通的函数。
我们知道有一个网站叫做Can I Use,打开网站以后,我们搜索arrow functions ,我们看看chrome是在哪个版本开始支持箭头函数的。
从图中我们可以看到,chrome在版本45及以后的版本开始支持箭头函数。
有了这些信息,我们来修改下Babel的配置文件,修改如下地方
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"chrome": "43"
"chrome": "45"
},
"useBuiltIns": "usage",
"corejs": "3.6.5"
}
]
]
}重新运行编译命令
./node_modules/.bin/babel index.js --out-dir lib奇妙的事情发生了,我们经过编译过后的文件lib/index.js中,箭头函数还是被编译成了简单函数,诶?
Can I use上不是说chrome在版本45及以后就支持箭头函数了么,按道理,箭头函数不应该被编译成普通函数了啊,这是怎么回事儿?
原因是Babel认为在这种刚开始支持某种特性的版本中,一些边缘条件下,仍有出错的可能性,所以Babel选择了增大这个版本号,也就是后面的版本对bug都修复的差不多了。Babel认为,这个特性在这个版本的浏览器中已经足够安全可以使用了,才不会对它进行编译。
那么我们去哪里知道在哪个版本以后,Babel才会认为箭头函数是安全的呢?打开如下链接。
Babel在仓库中维护了一个类似数据库的内容。
{
"transform-arrow-functions": {
"chrome": "47",
"opera": "34",
"edge": "13",
"firefox": "43",
"safari": "10",
"node": "6",
"deno": "1",
"ios": "10",
"samsung": "5",
"rhino": "1.7.13",
"opera_mobile": "34",
"electron": "0.36"
}
}我们可以看到,在chrome47以后,箭头函数就不会被编译成普通函数了,我们可以通过修改Babel配置文件,来验证。
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"chrome": "43"
"chrome": "47"
},
"useBuiltIns": "usage",
"corejs": "3.6.5"
}
]
]
}通过验证,我们可以发现,这次Babel没有对箭头函数进行编译了。
"use strict";
// Babel 演示代码
console.log('Hello from Babel demo!');
// 示例:使用 ES6+ 语法
var greeting = name => {
return `Welcome to Babel, ${name}!`;
};所以当我们遇到这些类似为什么Babel要这样去转换的问题时,都可以用类似的方法去分析,进而找到答案。