Skip to content

BabelJs - 使用 Babel 7 进行项目设置

BabelJS - 使用 Babel 7+ 进行项目设置

Section titled “BabelJS - 使用 Babel 7+ 进行项目设置”

Babel 7(及后续版本)引入了重大的改进和变化,主要是将包命名到 @babel 命名空间下。例如,babel-core 变成了 @babel/core,babel-cli 变成了 @babel/cli。本章将指导您使用现代 Babel 设置一个基本项目。

让我们创建一个新项目并配置 Babel。

首先,创建一个项目目录并使用 npm(Node 包管理器)进行初始化:

mkdir my-babel-project
cd my-babel-project
npm init -y

这将创建一个包含默认设置的 package.json 文件。

安装核心 Babel 包作为开发依赖(devDependencies):

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

我们来解释一下这些包:

  • @babel/core:Babel 的主要引擎。进行任何 Babel 转换都需要它。
  • @babel/cli:命令行界面,用于从终端运行 Babel。
  • @babel/preset-env:一个智能预设,允许您使用最新的 JavaScript,而无需为目标环境手动管理语法转换(或垫片!)。它会根据您支持的环境自动确定所需的 Babel 插件和垫片。

安装完成后,您的 package.json 的 devDependencies 部分将类似于以下内容(版本可能有所不同):

{
// ... other package.json content ...
"devDependencies": {
"@babel/cli": "^7.x.x",
"@babel/core": "^7.x.x",
"@babel/preset-env": "^7.x.x"
}
}

创建 Babel 配置文件。您可以使用 babel.config.json(推荐用于项目范围的配置)或在项目根目录中使用 .babelrc.json。我们使用 babel.config.json:

babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1",
"node": "current" // Or a specific version like "12"
}
}
]
]
}

在此配置中:

  • 我们指定了 @babel/preset-env。
  • targets 选项告诉 @babel/preset-env 您要支持哪些环境。然后 Babel 将仅转译这些环境不支持的特性,这可能会生成更小的输出文件并加快构建速度。您可以在这里找到更多关于 targets 的信息:https://babeljs.io/docs/babel-preset-env#targets

为您的 JavaScript 源文件创建一个 src 目录。我们添加一个包含一些现代 JavaScript 的 main.js 文件:

src/main.js
const add = (a, b) => a + b;
const name = "Babel User";
console.log(`Hello, ${name}! The sum of 5 and 10 is ${add(5, 10)}.`);
class Greeter {
constructor(greeting) {
this.greeting = greeting;
}
greet(person) {
return `${this.greeting}, ${person}!`;
}
}
const greeter = new Greeter("Hi there");
console.log(greeter.greet("Developer"));

您现在可以使用 Babel CLI 转译代码。最好在 package.json 中添加一个脚本:

// package.json - add to "scripts" section
"scripts": {
"build": "babel src --out-dir lib",
"test": "echo \"Error: no test specified\" && exit 1"
}

现在,运行构建脚本:

npm run build

此命令告诉 Babel 获取 src 目录中的所有文件,进行转译,并将它们输出到 lib 目录,同时保持原始文件结构。

运行后,您将找到一个 lib/main.js 文件。其内容将是 src/main.js 的 ES5 兼容版本:

// lib/main.js (Example output, may vary slightly)
"use strict";
function _classCallCheck(instance, Constructor) { /* ... helper ... */ }
function _defineProperties(target, props) { /* ... helper ... */ }
function _createClass(Constructor, protoProps, staticProps) { /* ... helper ... */ }
var add = function add(a, b) {
return a + b;
};
var name = "Babel User";
console.log("Hello, ".concat(name, "! The sum of 5 and 10 is ").concat(add(5, 10), "."));
var Greeter = /*#__PURE__*/function () {
function Greeter(greeting) {
_classCallCheck(this, Greeter);
this.greeting = greeting;
}
_createClass(Greeter, [{
key: "greet",
value: function greet(person) {
return "".concat(this.greeting, ", ").concat(person, "!");
}
}]);
return Greeter;
}();
var greeter = new Greeter("Hi there");
console.log(greeter.greet("Developer"));

核心功能保持不变,但像箭头函数和类这样的语法已被转换为旧的等效形式。Babel 在需要时还会添加辅助函数(如 _classCallCheck)用于转换。

Babel 也可以转译 TypeScript。首先,安装 TypeScript 预设:

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

然后,将其添加到您的 babel.config.json 中(如果在 @babel/preset-env 之前,则 env 将处理其输出):

babel.config.json
{
"presets": [
"@babel/preset-typescript", // Add this
[
"@babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
]
}

创建一个 TypeScript 文件,例如 src/person.ts:

src/person.ts
interface Person {
firstName: string;
lastName: string;
}
function getFullName(person: Person): string {
return `Hello, ${person.firstName} ${person.lastName}`;
}
const user: Person = { firstName: "Ada", lastName: "Lovelace" };
console.log(getFullName(user));

更新您的 package.json 构建脚本以包含 .ts 文件(如果您的 CLI 命令没有自动处理,尽管现代 Babel CLI 通常在配置了扩展名后会自动处理):

// package.json - "scripts" section
"scripts": {
"build": "babel src --out-dir lib --extensions \".ts,.js\"",
// ...
}

运行 npm run build。Babel 将去除 TypeScript 类型并转译剩余的 JavaScript。lib/person.js 中的输出将是标准的 JavaScript:

// lib/person.js (Example output)
"use strict";
function getFullName(person) {
return "Hello, ".concat(person.firstName, " ").concat(person.lastName);
}
var user = {
firstName: "Ada",
lastName: "Lovelace"
};
console.log(getFullName(user));

注意:@babel/preset-typescript 仅执行转译(去除类型)。它不执行类型检查。对于类型检查,您仍然需要使用 TypeScript 编译器(tsc)。许多项目使用 tsc 进行类型检查,而使用 Babel 进行转译。

随着 Babel 7+ 的发布,像 babel-preset-es2015、babel-preset-es2016 等以及 babel-preset-latest 等旧的预设都已弃用,取而代之的是 @babel/preset-env。

用于实验性特性的 Stage 预设(例如 babel-preset-stage-0)也已被移除。如果您需要实验性特性,通常会直接包含它们特定的提案插件。更多信息请参阅:https://babeljs.io/blog/2018/07/27/removing-babels-stage-presets

插件名称也发生了变化。例如,babel-plugin-transform-es2015-classes 变成了 @babel/plugin-transform-classes。@babel/preset-env 会根据您的目标环境为您管理这些插件。