babel使用指南(翻译)

190 阅读6分钟

原文:www.babeljs.cn/docs/usage 版本:7.8.0

在Babel工具链中有很多工具试图让您更容易地使用Babel,无论您是“最终用户”还是构建Babel本身的集成。这将是对这些工具的快速介绍,您可以在文档的“用法”部分阅读更多关于它们的信息。

如果您使用的是一个框架,那么配置Babel的工作可能会有所不同,或者实际上已经为您处理好了。请查看我们的交互式指南

概述

本指南将向您展示如何将使用ES2015+语法的JavaScript应用程序代码编译为可在当前浏览器中工作的代码。这将涉及到转换新的语法和填充缺失的特性。

整个设置过程包括:

  • 运行以下命令以安装软件包:

      npm install --save-dev @babel/core @babel/cli @babel/preset-env
      npm install --save @babel/polyfill
    
  • 创建名为babel.config.json的配置文件在包含此内容的项目根目录中:

      {
        "presets": [
          [
            "@babel/env",
            {
              "targets": {
                "edge": "17",
                "firefox": "60",
                "chrome": "67",
                "safari": "11.1",
              },
              "useBuiltIns": "usage",
            }
          ]
        ]
      }
    

上面列出的浏览器只是一个任意的例子。你必须根据你想要支持的浏览器来调整它。

  • 并运行此命令将src目录中的所有代码编译到lib:

      ./node_modules/.bin/babel src --out-dir lib
    

    您可以使用附带的npm包运行器npm@5.2.0通过用npx babel替换./node_modules/.bin/babel来缩短该命令

CLI的基本用法

您需要的所有Babel模块都作为单独的npm包发布在@Babel下(从版本7开始)。这种模块化设计允许各种工具,每个工具都针对特定的用例而设计。在这里我们来看看@babel/core和@babel/cli。

Core Library(核心库)

Babel的核心功能位于@Babel/core模块中。安装后:

npm install --save-dev @babel/core

您可以直接在JavaScript程序中require 它,并按如下方式使用:

const babel = require("@babel/core");

babel.transform("code", optionsObject);

但是作为最终用户,您可能希望安装其他工具,作为@babel/core的接口,并与您的开发过程很好地集成。即使如此,您可能仍然需要查看它的文档页面来了解选项,其中大多数选项也可以从其他工具中设置。

CLI tool(CLI工具)

@babel/cli是一个允许您从终端使用babel的工具。以下是安装命令和基本用法示例:

npm install --save-dev @babel/core @babel/cli

./node_modules/.bin/babel src --out-dir lib

这将解析src目录中的所有JavaScript文件,应用我们告诉它的任何转换,并将每个文件输出到lib目录。因为我们还没有告诉它应用任何转换,所以输出代码将与输入相同(不保留精确的代码样式)。我们可以通过将它们作为选项传递来指定所需的转换。

我们使用了上面的--out dir选项。您可以通过运行cli工具的--help查看其他选项。但现在最重要的是--plugins和--presets。

Plugins & Presets(插件和预置)

转换以插件的形式出现,插件是一种小型JavaScript程序,用于指导Babel如何对代码进行转换。你甚至可以编写自己的插件来应用你想要的任何代码转换。要将ES2015+语法转换为ES5,我们可以依赖官方插件,如@babel/plugin-transform-arrow-functions函数:

npm install --save-dev @babel/plugin-transform-arrow-functions

./node_modules/.bin/babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions

现在,我们代码中的任何箭头函数都将转换为与ES5兼容的函数表达式:

const fn = () => 1;

// converted to

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

这是个好的开始!但我们的代码中还有其他需要转换的ES2015+功能。我们不需要一个接一个地添加所有需要的插件,而是使用一个“预置”,它只是一组预先确定的插件。

就像插件一样,你也可以创建你自己的预置来共享你需要的任何插件组合。对于我们这里的用例,有一个很好的预置名为env。

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

./node_modules/.bin/babel src --out-dir lib --presets=@babel/env

没有任何配置,这个预置将包括所有支持现代JavaScript(ES2015、ES2016等)的插件。但是预设也可以选择。与其从终端同时传递cli和预设选项,不如看一下传递选项的另一种方法:配置文件。

Configuration(配置)

根据您的需要,有几种不同的方法来使用配置文件。请务必阅读我们关于如何配置Babel的深入指南以了解更多信息。

现在,让我们创建一个名为babel.config.json包括以下内容:

const presets = [
  [
    "@babel/env",
    {
      targets: {
        edge: "17",
        firefox: "60",
        chrome: "67",
        safari: "11.1",
      },
    },
  ],
];

module.exports = { presets };

现在env预置只为目标浏览器中不可用的特性加载转换插件。我们都准备好了语法。接下来我们来看看polyfills。

Polyfill(多边形)

从Babel 7.4.0开始,这个包已经被弃用,而是直接包含core-js/stable(polyfill-ECMAScript特性)和regenerator-runtime/runtime(需要使用transpiled generator函数):

import "core-js/stable";
import "regenerator-runtime/runtime";

@babel/polyfill模块包括core-js和一个定制的 regenerator runtime时,以模拟完整的ES2015+环境。

这意味着您可以使用像PromiseWeakMap这样的新的内置函数,静态方法比如Array.from或者Object.assign,实例方法如Array.prototype.includes,和生成器函数(与再生器插件一起使用时)。为了做到这一点,polyfill添加了全局范围和本机原型(如String)。

对于库/工具作者来说,这可能太多了。如果您不需要像Array.prototype.includes通过使用 transform runtime插件而不是@babel/polyfill,您可以完全不污染全局范围。

更进一步,如果您确切地知道需要polyfills的功能,可以直接从core js中require 它们。

npm install --save @babel/polyfill

注意--save选项而不是--save dev,因为这是一个需要在源代码之前运行的polyfill。

现在幸运的是,我们使用的是env预置,它有一个“useBuiltIns”选项,当设置为“usage”时,实际上会应用上面提到的最后一个优化,其中只包含您需要的polyfill。使用此新选项,配置更改如下:

{
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "edge": "17",
          "firefox": "60",
          "chrome": "67",
          "safari": "11.1",
        },
        "useBuiltIns": "usage",
      }
    ]
  ]
}

Babel现在将检查您的所有代码中缺少的功能,只包括所需的polyfill。例如,此代码:

Promise.resolve().finally();

会变成这样(因为Edge 17没有Promise.prototype.finally):

require("core-js/modules/es.promise.finally");

Promise.resolve().finally();

如果我们不使用env预置,并将“useBuiltIns”选项设置为“usage”,我们将不得不在任何其他代码之前在入口点只需要一次完整的polyfill。

摘要

我们使用@babel/cli从终端运行babel,@babel/polyfill来polyfill所有新的JavaScript特性,env预置只包含我们使用的和目标浏览器中缺少的功能的转换和polyfill。

有关使用构建系统、IDE等设置Babel的更多信息,请查看我们的交互式设置指南