合拾

Babel指南

2019-01-09

Babel是一个JavaScript编译器,可以让我们在项目中随心所欲的使用ES6/7/8的语法,而不受浏览器环境的限制。 本文介绍Babel相关工具的一些基础知识。

image

Babel是一个JavaScript编译器,可以让我们在项目中随心所欲的使用ES6/7/8的语法,而不受浏览器环境的限制。随着Babel7的发布,在开发体验和性能上也带来了很大提升,本文也是介绍Babel7相关的知识。

写这篇文章是为了介绍在项目实际开发中所用到的一些Babel相关的工具和插件,诸如babel-cli、babel-core、babel-preset-env。通常,不熟悉的同学看到这样一堆带有babel前缀的东西可能会云里雾里,本文希望能为你解答疑惑。

Babel7带来的最直观的变化是:Babel 团队会通过使用 “scoped” packages 的方式,来给自己的 babel package name 加上 @babel 命名空间,这样以便于区分官方 package 以及 非官方 package,所以 babel-core 会变成 @babel/core。

配置文件

.babelrc是babel的配置文件,存放于项目的根目录下,当你使用babel工具对JS代码进行编译时,babel对自动寻找配置文件。
.babelrc文件主要用来配置编译规则和编译插件,编译规则和插件也需要额外安装。配置文件格式如下:

{
"presets":["@babel/react", "@babel/env"],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }],
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-runtime"
]
}

plugin字段设置用于转换特定语法的插件,而一个特定的preset可以理解为一组特定的plugins的集合。
presets字段设定编译规则,用于设置开启的语法特性集合,目前最常用的preset是@babel/preset-env。

根据支持环境自动选择编译规则

默认情况下,所有已被纳入规范的语法(ES2015、ES2016、ES2017、ES2018、Modules)所需要的plugins都包含在这个preset中。

安装@babel/preset-env:

npm install --save-dev @babel/preset-env

@babel/preset-env 会根据 browserlist 配置进行转换。但是,env这个preset只包含了规范中的语法转换,处于提案阶段尚未纳入规范的各个阶段的提案,还是需要单独适用plugin来进行转换。例如处于state-2(drft)阶段的装饰器语法,需要使用@babel/plugin-proposal-decorators进行转换。

react编译规则

在编写react项目时需要用到@babel/preset-react,其中包含了@babel/plugin-syntax-jsx、@babel/plugin-transform-react-jsx、@babel/plugin-transform-react-display-name等插件。

安装@babel/preset-react:

npm install --save-dev  @babel/preset-react

plugins字段用于转译特定语法的插件,如上述配置中@babel/plugin-proposal-decorators用于转换装饰器Decorator语法,
@babel/plugin-proposal-class-properties用于转换静态类属性以及使用属性初始化程序语法声明的属性。

@babel/cli

babel-cli是babel官方提供的一个CLI工具,用于在命令行编译JS文件。
可以通过以下命令本地安装 Babel CLI:

npm install --save-dev @babel/cli

安装完成后可以直接在命令行使用babel命令。

@babel/node

babel 提供的第二个 CLI工具,其功能与 Node.js 的 CLI 完全相同,只是它会在运行之前编译 ES6 代码。
它不用单独安装,而是随babel-cli一起安装。然后,执行babel-node就进入PEPL环境。
请不要在生产环境中使用 babel-node,因为它是动态编译源代码,应用启动速度非常慢。

安装:

npm install --save-dev @babel/node

@babel/core

babel-core是Babel用于解析、转换、代码生成的核心依赖包,一般在大型项目中使用babel都需要安装这个包。
安装:

npm install @babel/core --save-dev

如果某些代码需要调用babel的API进行转换,就需要使用babel-core。

@babel/polyfill

Babel默认只会转换新的JavaScript语法(Syntax),而不会转换新的API(如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法如Object.assign)。
babel-polyfill会仿效一个完整的 ES2015+ 环境,并意图运行于一个应用中而不是一个库/工具,为当前环境提供一个垫片。这个 polyfill 会在使用 babel-node 时自动加载。

安装:

npm install --save @babel/polyfill

因为这是一个 polyfill (它需要在你的源代码之前运行),我们需要让它成为一个 dependency, 而不是一个 devDependency.

你需要在你的应用入口顶部通过 require 将 polyfill 引入进来。确保它在任何其他代码、依赖声明之前被调用!

import '@babel/polyfill';
// 或者
require('@babel/polyfill');

缺点:引入babel-polyfill会污染全局变量,而且项目打包后的体积会变得庞大,在实际应用中,按需引入polyfill才是最好的实践。

@babel/runtime、@babel/plugin-transform-runtime

为了提供polyfill,babel提供了一些辅助方法helper,默认情况下这些辅助代码会被添加到每一个需要它的文件中,编译后可能会出现多个文件都会有重复的代码。使用babel-runtime和babel-plugin-transform-runtime,可以避免重复引入helper代码,此外,还可以。

安装:

npm install @babel/runtime @babel/plugin-transform-runtime --save-dev

使用:

// .babelrc
{
"presets": ["@babel/env"],
"plugins": [@babel/plugin-transform-runtime]
}

举个例子,如果当前运行环境不支持Promise,babel-runtime会引入babel-runtime/core-js/promise来获取Promise,或者通过babel-plugin-transform-runtime来自动重写Promise。其实在最开始只有babel-runtime插件,使用起来很不方便,在每个文件都内联使用了helper代码,导致最终打包出来的文件里有很多helper代码,所以出现了babel-plugin-transform-runtime,它会将我们的代码重写,如将Promise重写成_Promise,然后引入_Promise的helper函数。这样就避免了重复打包代码和手动引入模块的痛苦。

@babel/register

babel-register用于Node项目中,提供Require 钩子把自己绑定到 node 的 require 上并自动编译文件。

安装:

npm install @babel/register --save-dev

使用:

require("@babel/register");
require("./index.js");

通过 node 引入的带 .es6, .es, .jsx 和 .js 后缀的所有后续文件都将会被 Babel 转译。

@babel/preset-env

babel-preset-env是babel目前最为推荐使用的一个转译规则。它可以根据你支持的环境自动决定适合你的 Babel 插件,相当于JavaScript的Autoprefixer。

安装:

npm install @babel/preset-env --save-dev

在没有任何配置选项的情况下,babel-preset-env 与 babel-preset-latest(或者babel-preset-es2015,babel-preset-es2016和babel-preset-es2017一起)的行为完全相同。

{
"presets": ["@babel/env"]
}

@babel/preset-react

babel-preset-react用于转换React的JSX语法以及去除类型注释。
安装:

npm install --save-dev @babel/preset-react

并添加 “react” 到你的 .babelrc 的 presets 数组中。

{
"presets": ["@babel/react"]
}

参考文章

  1. @babel/polyfill 与 @babel/plugin-transform-runtime 详解

  2. Show me the code,babel 7 最佳实践!

  3. https://github.com/jamiebuilds/babel-handbook

Tags: Babel
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章