11 月 19 - 20 日 Apache Pulsar 社区年度盛会来啦,立即报名! 了解详情
写点什么

Babel 7.0 正式发布,支持 TypeScript,JSX Fragment

  • 2018-08-30
  • 本文字数:0 字

    阅读完需:约 1 分钟

由于 JavaScript 在不断地发展,各种新标准和提案也就层出不穷,用户使用的浏览器也不同(尤其是旧版的 IE),这就导致了有些用户无法使用 JavaScript 的一些新特性,如果开发人员想使用新的语法(如 class A {}),在旧浏览器上就会因为这个问题出现 SyntaxError。

由于它能够转换 JavaScript 代码,还可用于实现新功能,因此它已成为 TC39 获取社区对 JavaScript 反馈的重要桥梁。

如今,Babel 是 JavaScript 开发的基础。它在 npm 上,每月有 1700 万次的下载量,用户包括主流框架(React,Vue,Ember,Polymer)的开发者和企业(Facebook,Netflix,Airbnb)。即使你自己没有使用它,你的依赖项也很可能正在使用 Babel。

Babel 由志愿者驱动

虽然 Babel 对 JavaScript 语言的未来,甚至对社区和 js 生态都产生了巨大的影响,但你肯定想不到,他们的维护者只是由社区的几个志愿者组成。

重大变更

  • 不再支持不在维护中的 Node 版本:0.10、0.12、4、5;

  • 使用 @babel 命名空间,因此 babel-core 就变成了 @babel/core;

  • 移除(并停止发布)任何年度预设(preset-es2015 等),@babel/preset-env 取代了对这些内容的需求 ;

  • 移除“Stage” 预设(@babel/preset-stage-0 等),同时移除了 @babel/polyfill 中的提议;

  • 重命名了某些包:任何 TC39 提议插件现在都是 -proposal 而不是 -transform,所以 @babel/plugin-transform-class-properties 变成了 @babel/plugin-proposal-class-properties;

  • 针对某些面向用户的包(例如 babel-loader、@babel/cli 等)在 @babel/core 中引入 peerDependency;

babel-upgrade

babel-upgrade 是一个用于进行自动升级的新工具:目前在 package.json 和.babelrc 配置文件中配置了依赖关系。

建议直接在 git 仓库上运行 npx babel-upgrade,或者使用 npm i babel-upgrade -g 进行全局安装。

如果你想修改文件,可以使用参数 --write 和 --install。

复制代码
npx babel-upgrade --write --install

JavaScript 配置文件

Babel 7.0 引入了 babel.config.js。

*.js 配置文件在 JavaScript 生态系统中相当常见。ESLint 和 Webpack 分别使用了.eslintrc.js 和 webpack.config.js 配置文件。但这并不意味着它们就取代了.babelrc 或 package.json,这不是必要条件,但在某些情况下这可能很有用。以下是仅在“生产”环境中使用插件进行编译的配置。

babel.config.js 的配置解析方式与.babelrc 不同。它始终会解析该文件中的配置,而不会从每个文件向上查找,直到找到配置为止。这样就可以利用 overrides 特性。

复制代码
var env = process.env.NODE_ENV;
module.exports = {
 plugins: [
   env === "production" && "babel-plugin-that-is-cool"
 ].filter(Boolean)
};

使用 overrides 进行选择性配置

复制代码
module.exports = {
presets: [
// defeault config...
],
overrides: [{
test: ["./node_modules"],
presets: [
// config for node_modules
],
}, {
test: ["./tests"],
presets: [
// config for tests
],
}]
};

有些应用程序需要针对测试、客户端代码和服务器代码使用不同的编译配置选项,通过这种方式就不需要在每个文件夹下创建.babelrc 文件了。

速度

Babel 团队做了很多变更来优化代码,并接受了来自 V8 团队的一些补丁( https://twitter.com/rauchg/status/924349334346276864 )。

输出选项

Babel 支持预设和插件选项有一段时间了。比如,你可以将插件包装在一个数组中,并将选项对象传给插件:

复制代码
// 减号表示移除,加号表示增加:
{
"plugins": [
- "pluginA",
+ ["pluginA", {
+ // options here
+ }],
]
}

Babel 团队还对部分插件的 loose 选项做了一些修改,并为部分插件添加了一些新选项!

比如,对于类 class A {},现在不包含 _classCallCheck。

复制代码
class A {}
-------------------
// 减号表示移除:
var A = function A() {
- _classCallCheck(this, A);
};

如果 for-of 循环的是一个数组,那么可以使用这个新选项:[“transform-for-of”,{“assumeArray”:true}]

复制代码
let elm;
for (elm of array) {
console.log(elm);
}
----------------------
let elm;
for (let _i = 0, _array = array; _i < _array.length; _i++) {
elm = _array[_i];
console.log(elm);
}

在 loose 模式下将 transform-typeof-symbol 插件排除在外。

“纯粹”的注解支持

转换后的 ES6 类使用 /*#__PURE__*/ 进行注解,这样就可以告诉 Uglify 和 babel-minify 移除死代码。这些注解也被添加到其他辅助函数中。

复制代码
class C {
m() {}
}
---------------------
var C =
/*#__PURE__*/
function () {
// ...
}();

TC39 提案支持

以下是 Babel 支持的一些新语法以及已经添加到 v7 中的语法清单:

  • ES2018:Object Rest Spread (var a = { b, ...c })

  • ES2018(新):Unicode 属性正则表达式

  • ES2018(新):JSON 超集

  • ES2015(新):new.target

  • 阶段 3(新):类私有实例字段(class A { #b = 2 })

  • 阶段 3(WIP):静态类字段、私有静态方法(class A { static #a() {} })

  • 阶段 3(新):可选 Catch 绑定 try { throw 0 } catch { do() }

  • 第 3 阶段(新):BigInt(仅限语法)

  • 第 3 阶段:动态导入(import("a"))

  • 第 2 阶段(新):import.meta(仅限语法)(import.meta.url)

  • 第 2 阶段(新):数字分隔器(1_000)

  • 第 2 阶段(新):function.sent

  • 第 2 阶段:export-namespace-from(export * as ns from'mod'),从 export-extensions 中拆分出来

  • 第 2 阶段:装饰器

  • 第 1 阶段:export-default-from(export v from 'mod'),从 export-extensions 中拆分出来

  • 第 1 阶段(新):可选链接(a?.b)

  • 第 1 阶段(新):逻辑赋值(a &&= b; a ||= b)

  • 第 1 阶段(新):Nullish Coalescing(a ?? b)

  • 第 1 阶段(新):管道操作符(a |> b)

  • 第 1 阶段(新):throw 表达式(() => throw new Error("a"))

TypeScript 支持

Babel 团队与 TypeScript 团队合作,让 Babel 使用 @babel/preset-typescript 解析 / 转换类型语法,类似于使用 @babel/preset-flow 处理 Flow 的方式。

之前(有类型):

复制代码
interface Person {
firstName: string;
lastName: string;
}
function greeter(person : Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}

之后(移除了类型):

复制代码
function greeter(person) {
return "Hello, " + person.firstName + " " + person.lastName;
}

JSX Fragment 支持(<>)

正如 React 博客中所提到的,从 Beta.31 开始,已经支持 JSX Fragment。

复制代码
render() {
return (
<>
<ChildA />
<ChildB />
</>
);
}
-----------------------
// output
render() {
return React.createElement(
React.Fragment,
null,
React.createElement(ChildA, null),
React.createElement(ChildB, null)
);
}

Babel 辅助函数的变化

@babel/runtime 已经被分为 @babel/runtime 和 @babel/runtime-corejs2。前者仅包含 Babel 的辅助函数,后者包含辅助函数以及 polyfill 函数(例如 Symbol、Promise)。

规范规定了需要通过 new Person() 实例化一个类,但如果它被编译成一个函数,就可以直接调用 Person(),所以他们提供了一个运行时检查。

复制代码
class Person {}
------------------------
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Person = function Person() {
_classCallCheck(this, Person);
};

使用 @babel/plugin-transform-runtime 和 @babel/runtime(作为依赖项),Babel 可以提取单个函数,而且只需要模块函数来获得较小的输出,如下所示:

复制代码
var _classCallCheck = require("@babel/runtime/helpers/classCallCheck");
var Person = function Person() {
_classCallCheck(this, Person);
};

自动 polyfill(实验性质)

要使用 polyfill,只需导入 @babel/polyfill 即可:

复制代码
import "@babel/polyfill";

但这样会导入整个 polyfill,如果浏览器已经支持某些特性,就不需要导入所有内容。可以使用选项 useBuiltins:”entry”来导入需要用到的部分。

可以更进一步,通过选项 useBuiltIns:”usage”只将需要用到的 polyfill 导入到代码库中。

它将遍历每个文件,并在每个使用了内置 polyfill 的文件的顶部注入一个导入语句。例如:

复制代码
import "core-js/modules/es6.promise";
var a = new Promise();

但它的推理不是很完美,可能会出现误报:

复制代码
import "core-js/modules/es7.array.includes";
a.includes // assume a is an []

Babel 宏

Babel 的一大特点是它的可插拔性。多年来,Babel 从一个“6to5”编译器转变为代码转换平台,为用户和开发人员提供了出色的优化选项。人们已经为特定库和用例开发了大量的 Babel 插件,用以提升库 API 的性能和功能。

可惜的是,将这些插件添加到代码库中需要更改配置,从而增加了代码复杂性。由 Kent C. Dodds 开发的 babel-plugin-macros(https://github.com/kentcdodds/babel-plugin-macros)已经解决了这个!

在安装了 babel-plugin-macros 并将其添加到配置中(它已包含在 create-react-app v2 中)之后,你就不必费心配置就可以使用宏了。此外,为特定应用程序或代码编写自定义转换也变得更加容易。

模块目标

Babel 一直试图在转换的影响范围和功能之间做出平衡。在 Babel 7 中,通过配置 Babel 来支持模块 / 非模块模式变得更加容易。

值得注意的是,一些流行的 Web 框架的 CLI 工具已经在利用这些支持,这让转换后的 JavaScript 代码减少了大约 20%。

class C extends HTMLElement {}

Babel 总是会警告说它不支持扩展原生内置元素(Array、Error 等),但现在可以了!Babel 团队对类插件进行了修改,如果你使用了 preset-env,那么默认就自动启用了这个特性。

网站变更

Babel 网站从 Jekyll(https://jekyllrb.com/)搬到了 Docusaurus(https://docusaurus.io/)。

REPL

Babel 将 REPL 重写为 React 组件,并更好地与 CodeSandbox 集成。这样你就可以在 REPL 中安装来自 npm 的任何插件或预设,并获取 CodeSandbox 的任何更新。

接下来要做什么

Babel 本质上就是要与 JavaScript 紧紧联系在一起,包括在语法变得“稳定”之前花时间和精力来实现和维护语法。Babel 团队关心的是整个过程:升级路径、新特性的传播、标准 / 语言设计的教学、易用性以及与其他项目的集成。

在 Nicolò的帮助下,Babel 团队几乎完成了新的装饰器的实现。这是一个漫长的旅程,因为新的提案完全不同,而且比旧的更强大。它可能会在下一个次要版本中发布。

还有很多新特性还在开发当中:插件顺序、更好的验证 / 错误、速度提升、新的 loose/spec 选项、缓存、异步使用 Babel、从 CI 构建、冒烟测试、运行 test262。

查看英文原文: https://babeljs.io/blog/2018/08/27/7.0.0

感谢覃云对本文的审校及策划。

2018-08-30 19:003429

评论

发布
暂无评论
发现更多内容

极客大学架构师训练营大作业

Meow

智能电车小白从入门到了解(Day1/28)

mtfelix

自动驾驶 28天写作 智能电车 电动汽车

技术人小故事-团队愿景篇-第1段

Ian哥

28天写作

芯片破壁者(二十四):1987战役启示录

脑极体

架构师第 4 课作业及学习总结

小诗

「架构师训练营第 1 期」

职业成长就是一个逐渐“变帅”的过程

俊毅

架构师训练营第七周课后作业

万有引力

MySQL慢查询(上):为啥会这么慢?

架构精进之路

MySQL MySQL优化 MySQL使用 28天写作

SpringBoot系列1——概述和快速入门

程序员的时光

springboot 七日更 28天写作

牛啤了!阿里技术官整理的这份《Java面试手册5000题》已经成功让数百名社招生“圆梦BATJ”

Java 编程 面试

缓存穿透,缓存击穿,缓存雪崩

en

redis 缓存穿透 缓存击穿 缓存并发

架构师训练营 1 期 - 第 十四周总结(vaik)

行之

「架构师训练营第 1 期」

资深大牛带你了解源码!阿里内部Android笔记火爆IT圈,醍醐灌顶!

欢喜学安卓

android 程序员 面试 移动开发

jstat使用实用教程

JavaPub

Java JVM

爱了! Alibaba技术官甩出的“阿里内部Java成长笔记”,差距对比真的是不止一点点

Java架构之路

Java 程序员 架构 面试 编程语言

普通职场打工人如何快速拥有老板思维,改变自己的命运【28天写作】

程序员陆通

职场 28天写作 老板思维

【薪火计划】08 - 非暴力沟通

dstweihao

管理 28天写作

手把手教你如何巧用Github的Action功能

flutter android 持续集成

网络工程师职业指南

MySQL中的哥哥表、妹妹字段,是什么鬼?

Java MySQL 数据库

腾讯T3面试官透露!360°深入了解Flutter,聪明人已经收藏了!

欢喜学安卓

android 程序员 面试 移动开发

关于拼多多价值的思考

.

28天写作

LeetCode题解:17. 电话号码的字母组合,BFS,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

架构师第 3 课作业及学习总结

小诗

「架构师训练营第 1 期」

意识会在哪个早晨降落——「幻想短篇1/28」

道伟

28天写作

谬误词典:置信度

lidaobing

随机漫步的傻瓜 28天写作 谬误词典

架构师训练营第 1 期 - 第 12 周 - 学习总结

wgl

「架构师训练营第 1 期」

架构师必会知识大合集:五位架构师手写于西溪园区的技术使用心得

Java架构之路

Java 程序员 架构 面试 编程语言

极客大学架构师训练营大作业

Meow

Babel 7.0正式发布,支持TypeScript,JSX Fragment_JavaScript_Babel博客_InfoQ精选文章