Babel 使用指南

2023-06-06 16:14 更新

Babel 工具鏈?zhǔn)怯纱罅康墓ぞ呓M成的,無論你是 “最終用戶” 還是在集成 Babel,這些工具都簡化了 Babel 的使用。本文是對這些工具的使用方法的快速介紹,你可以在文檔的 “用法” 章節(jié)了解到更多信息。

如果你正在使用的是一套框架,Babel 的配置可能會有所不同,也可能已經(jīng)自動為你配置好了。

概覽?

本指南將想你展示如何將 ES2015+ 語法的 JavaScript 代碼編譯為能在當(dāng)前瀏覽器上工作的代碼。這將涉及到新語法的轉(zhuǎn)換和缺失特性的修補(bǔ)。

整個配置過程包括:

  1. 運(yùn)行以下命令安裝所需的包(package):
    //npm命令
    npm install --save-dev @babel/core @babel/cli @babel/preset-env
    
    //Yarn命令
    

    yarn add --dev @babel/core @babel/cli @babel/preset-env

    //pnpm命令

    pnpm add --save-dev @babel/core @babel/cli @babel/preset-env

  2. 在項(xiàng)目的根目錄下創(chuàng)建一個命名為 babel.config.json 的配置文件(需要 v7.8.0 或更高版本),并將以下內(nèi)容復(fù)制到此文件中:
    babel.config.json
    {
      "presets": [
        [
          "@babel/preset-env",
          {
            "targets": {
              "edge": "17",
              "firefox": "60",
              "chrome": "67",
              "safari": "11.1"
            },
            "useBuiltIns": "usage",
            "corejs": "3.6.5"
          }
        ]
      ]
    }
    

    上述瀏覽器列表僅用于示例。請根據(jù)你所需要支持的瀏覽器進(jìn)行調(diào)整。參見 此處 以了解 @babel/preset-env 可接受哪些參數(shù)。

    如果你使用的是 Babel 的舊版本,則文件名為 babel.config.js
    babel.config.js

    const presets = [
      [
        "@babel/preset-env",
        {
          targets: {
            edge: "17",
            firefox: "60",
            chrome: "67",
            safari: "11.1",
          },
          useBuiltIns: "usage",
          corejs: "3.6.4",
        },
      ],
    ];
    
    module.exports = { presets };
  3. 運(yùn)行此命令將 src 目錄下的所有代碼編譯到 lib 目錄:
    Shell
    ./node_modules/.bin/babel src --out-dir lib
    

 你可以利用 npm@5.2.0 所自帶的 npm 包運(yùn)行器將 ./node_modules/.bin/babel 命令縮短為 npx babel

繼續(xù)閱讀后面的分步講解,了解其工作原理以及每個工具的功能。


CLI 命令行的基本用法

你所需要的所有的 Babel 模塊都是作為獨(dú)立的 npm 包發(fā)布的,并且(從版本 7 開始)都是以 @babel 作為冠名的。這種模塊化的設(shè)計(jì)能夠讓每種工具都針對特定使用情況進(jìn)行設(shè)計(jì)。 下面我們著重看一下 @babel/core 和 @babel/cli。

核心庫

Babel 的核心功能包含在 @babel/core 模塊中。通過以下命令安裝:

//npm命令
npm install --save-dev @babel/core

//Yarn命令

yarn add --dev @babel/core

//pnpm命令

pnpm add --save-dev @babel/core

你可以在 JavaScript 程序中直接 require 并使用它:

JavaScript

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

babel.transformSync("code", optionsObject);

作為一名最終用戶,你可以還需要安裝其他工具作為 @babel/core 的使用接口并很好地集成到你的開發(fā)流程中。即便如此,你仍然需要查看其文檔并了解可用的參數(shù),其中很多參數(shù)也可以通過其他工具進(jìn)行設(shè)置。


CLI 命令行工具?

@babel/cli 是一個能夠從終端(命令行)使用的工具。下面是其安裝命令和基本用法:

//npm命令
npm install --save-dev @babel/core @babel/cli
./node_modules/.bin/babel src --out-dir lib

//Yarn命令

yarn add --dev @babel/core @babel/cli

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

//pnpm命令

pnpm add --save-dev @babel/core @babel/cli

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

這將解析 ?src ?目錄下的所有 JavaScript 文件,并應(yīng)用我們所指定的代碼轉(zhuǎn)換功能,然后把每個文件輸出到 ?lib? 目錄下。由于我們還沒有指定任何代碼轉(zhuǎn)換功能,所以輸出的代碼將與輸入的代碼相同(不保留原代碼格式)。我們可以將我們所需要的代碼轉(zhuǎn)換功能作為參數(shù)傳遞進(jìn)去。

上面的示例中我們使用了 ?--out-dir? 參數(shù)。你可以通過? --help ?參數(shù)來查看命令行工具所能接受的所有參數(shù)列表。但是現(xiàn)在對我們來說最重要的是 ?--plugins ?和 ?--presets ?這兩個參數(shù)。


插件和預(yù)設(shè)(preset)

代碼轉(zhuǎn)換功能以插件的形式出現(xiàn),插件是小型的 JavaScript 程序,用于指導(dǎo) Babel 如何對代碼進(jìn)行轉(zhuǎn)換。你甚至可以編寫自己的插件將你所需要的任何代碼轉(zhuǎn)換功能應(yīng)用到你的代碼上。例如將 ES2015+ 語法轉(zhuǎn)換為 ES5 語法,我們可以使用諸如 ?@babel/plugin-transform-arrow-functions ?之類的官方插件:

//npm命令
npm install --save-dev @babel/plugin-transform-arrow-functions
./node_modules/.bin/babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions

//Yarn命令

yarn add --dev @babel/plugin-transform-arrow-functions

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

//pnpm命令

pnpm add --save-dev @babel/plugin-transform-arrow-functions

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

現(xiàn)在,我們代碼中的所有箭頭函數(shù)(arrow functions)都將被轉(zhuǎn)換為 ES5 兼容的函數(shù)表達(dá)式了:

JavaScript

const fn = () => 1;

// converted to

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

這是個好的開始!但是我們的代碼中仍然殘留了其他 ES2015+ 的特性,我們希望對它們也進(jìn)行轉(zhuǎn)換。我們不需要一個接一個地添加所有需要的插件,我們可以使用一個 "preset" (即一組預(yù)先設(shè)定的插件)。

就像插件一樣,你也可以根據(jù)自己所需要的插件組合創(chuàng)建一個自己的 preset 并將其分享出去。J對于當(dāng)前的用例而言,我們可以使用一個名稱為 ?env ?的 preset。

//npm命令
npm install --save-dev @babel/preset-env
./node_modules/.bin/babel src --out-dir lib --presets=@babel/env

//Yarn命令

yarn add --dev @babel/preset-env

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

//pnpm命令

pnpm add --save-dev @babel/preset-env

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

如果不進(jìn)行任何配置,上述 preset 所包含的插件將支持所有最新的 JavaScript (ES2015、ES2016 等)特性。但是 preset 也是支持參數(shù)的。我們來看看另一種傳遞參數(shù)的方法:配置文件,而不是通過終端控制臺同時傳遞 cli 和 preset 的參數(shù)。


配置

根據(jù)你的需要,可以通過幾種不同的方式來使用配置文件。另外,請務(wù)必閱讀我們關(guān)于如何 配置 Babel 的深入指南以了解更多信息。

現(xiàn)在,我們首先創(chuàng)建一個名為 babel.config.json 的文件(需要 v7.8.0 或更高版本),并包含如下內(nèi)容:

babel.config.json
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "edge": "17",
          "firefox": "60",
          "chrome": "67",
          "safari": "11.1"
        }
      }
    ]
  ]
}
現(xiàn)在,名為 env 的 preset 只會為目標(biāo)瀏覽器中沒有的功能加載轉(zhuǎn)換插件。語法都已經(jīng)清楚了,接下來我們看看 polyfills 。

Polyfill

 從 Babel 7.4.0 版本開始,這個軟件包已經(jīng)不建議使用了,建議直接包含 core-js/stable (用于模擬 ECMAScript 的功能):

JavaScript

import "core-js/stable";

如果您正在將生成器或異步函數(shù)編譯到ES5,并且您使用的是7.18.0之前的?@babel/core?或?@babel/plugin-transformat-regenerator?版本,則還必須加載 regenerator runtime 包。當(dāng)使用?@babel/preset-env的useBuiltIns:“usage”?選項(xiàng)或@babel/plugin-transform-runtime,它會自動加載。

@babel/polyfill 模塊包含 core-js 和一個自定義的 regenerator runtime 來模擬完整的 ES2015+ 環(huán)境。

這意味著你可以使用諸如 Promise 和 WeakMap 之類的新的內(nèi)置組件、 Array.from 或 Object.assign 之類的靜態(tài)方法、 Array.prototype.includes 之類的實(shí)例方法以及生成器函數(shù)(generator functions)(前提是你使用了 regenerator 插件)。為了添加這些功能,polyfill 將添加到全局范圍(global scope)和類似 String 這樣的原生原型(native prototypes)中。

對于軟件庫/工具的作者來說,這可能太多了。如果你不需要類似 Array.prototype.includes 的實(shí)例方法,可以使用 transform runtime 插件而不是對全局范圍(global scope)造成污染的 @babel/polyfill。

更進(jìn)一步,如果你確切地指導(dǎo)你所需要的 polyfills 功能,你可以直接從 core-js 獲取它們。

由于我們構(gòu)建的是一個應(yīng)用程序,因此我們只需安裝 @babel/polyfill 即可:

//npm 命令 
npm install --save @babel/polyfill

//Yarn命令 

yarn add @babel/polyfill

//pnpm命令

pnpm add @babel/polyfill

 注意,使用 --save 參數(shù)而不是 --save-dev,因?yàn)檫@是一個需要在你的源碼之前運(yùn)行的 polyfill。

幸運(yùn)的是,我們所使用的 env preset 提供了一個 "useBuiltIns" 參數(shù),當(dāng)此參數(shù)設(shè)置為 "usage" 時,就會加載上面所提到的最后一個優(yōu)化措施,也就是只包含你所需要的 polyfill。使用此新參數(shù)后,修改配置如下:

babel.config.json

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

Babel 將檢查你的所有代碼,以便查找目標(biāo)環(huán)境中缺失的功能,然后只把必須的 polyfill 包含進(jìn)來。示例代碼如下:

JavaScript

Promise.resolve().finally();

將被轉(zhuǎn)換為(由于 Edge 17 沒有 Promise.prototype.finally):

JavaScript

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

Promise.resolve().finally();

如果我們不使用將 "useBuiltIns" 參數(shù)設(shè)置為 "usage" (默認(rèn)值是 "false")的 env 預(yù)設(shè)的話,那么我們必須在所有代碼之前利用 require 加載 一次 完整的 polyfill。

例如:

babel.config.json

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

然后首先導(dǎo)入 core-js(到polyfill ECMAScript功能),在我們的入口文件中模擬完整的ES2015+環(huán)境,因?yàn)?a href="http://m.o2fo.com/babel/babelpolyfill.html" target="_blank">@pabel/polyfill已經(jīng)被棄用:

JavaScript

 import "core-js/stable";

總結(jié)

我們使用 @babel/cli 從終端運(yùn)行 Babel,利用 @babel/polyfill 來模擬所有新的 JavaScript 功能,而 env preset 只對我們所使用的并且目標(biāo)瀏覽器中缺失的功能進(jìn)行代碼轉(zhuǎn)換和加載 polyfill。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號