跳至主内容

6.23.0 版本发布

· 1 分钟阅读
非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

本次发布包含:@STRMLreact-constant-elements 插件的多项改进、代码生成优化以及大量错误修复!感谢 @loganfsmyth 负责版本发布和代码审查!

特别祝贺首次提交 PR 的贡献者:@xtina-starr, @finkef, @chitchu, @yongxu, @jwbay, @hex13!🎉

完整变更日志请查看 GitHub


我将很快撰写关于 7.0 版本(当前进展)的博文,敬请关注!我们会竭尽全力让终端用户和插件/工具开发者都能无缝升级:无论是发布测试版、提供 7.0 升级指南、必要时提供代码修改工具、创建自动升级开源项目的机器人,还是采纳大家提出的任何建议!

可能并非所有人都了解,我想再次强调:我们的团队仍是小型志愿者团体。既无企业赞助,也无人全职投入。

诚邀您参与贡献(尤其非代码类贡献)!欢迎随时联系我们!非常需要更多设计师、技术文档作者/编辑以及网站教学人员。

另外,Babel 已入选 Rails Girls 夏季编程项目,并正在等待成为 Google 编程夏令营的导师组织!


🚀 新特性

#5236 transform-es2015-block-scoping:新增选项 throwIfClosureRequired 以在低效代码处抛出错误 (@spicyj)

babel.config.json
{
"plugins": [
["transform-es2015-block-scoping", {
"throwIfClosureRequired": true
}]
]
}

在以下情况中,转换时若不添加额外函数和闭包,则无法重写 let/const:

JavaScript
for (let i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 1);
}

在极度关注性能的代码中,这可能不符合预期。若设置 "throwIfClosureRequired": true,Babel 遇到此类模式时会抛出错误,而非自动添加额外函数。

#4812 transform-react-constant-elements:支持纯表达式 (@STRML)

为插件增加了 path.isPure() 检查。

即使表达式可静态求值,仍会保留在提升后的代码中。UglifyJS/Babili 会在多数情况下处理此问题。

输入

JavaScript
const OFFSET = 3;

var Foo = React.createClass({
render: function () {
return (
<div tabIndex={OFFSET + 1} />
);
}
});

输入

JavaScript
const OFFSET = 3;

var _ref = <div tabIndex={OFFSET + 1} />;

var Foo = React.createClass({
render: function () {
return _ref;
}
});

降级处理

facebook/react#3226 所述,复用含可变属性的元素并不安全。

JavaScript
<div style={
{ width: 100 }
} />

#5288 新增 babel-preset-flow 预设 (@thejameskyle)

babel-preset-flow 仅包含 transform-flow-strip-types

之前(仍有效)

babel.config.json
{
"plugins": ["transform-flow-strip-types"]
}

优化后

babel.config.json
{
"presets": ["flow"]
}

注:React 预设默认仍包含 Flow 插件(未来添加 TS 支持时可能会调整)

感谢 @simnalamburt 为我们提供了这个包名!

#5230 babel-traverse: 新增额外兄弟节点方法 (@chitchu)

插件开发者注意:已有 path.getSibling(number) 方法,现新增几个辅助方法。

JavaScript
path.getPrevSibling(); // path.getSibling(path.parentPath.key - 1)
path.getNextSibling(); // path.getSibling(path.parentPath.key + 1)
path.getAllPrevSiblings(); // returns Array<NodePath> of previous siblings
path.getAllNextSiblings();// returns Array<NodePath> of next siblings

🐛 错误修复

几乎每个错误修复都是深入了解 JavaScript 及其工具运作原理的机会,建议查阅相关 PR!

#5298 修复带标签的松散模式 transform-es2015-for-of (@jridgewell)

JavaScript
b: for (let c of d()) { // previously, the label was completely dropped
for (let e of f()) {
continue b;
}
}

#5153 transform-react-constant-elements: 提升优化修复 (@STRML)

优化变量声明内部的提升效果

输入

JavaScript
function render() {
const bar = "bar", renderFoo = () => <foo bar={bar} baz={baz} />, baz = "baz";

return renderFoo();
}

输出

JavaScript
function render() {
const bar = "bar",
renderFoo = () => _ref2,
baz = "baz",
_ref2 = <foo bar={bar} baz={baz} />;

return renderFoo();
}

高阶组件中的提升优化

输入

JavaScript
const HOC = component => component;

const Parent = () => (
<div className="parent">
<Child/>
</div>
);

export default Parent;

let Child = () => (
<div className="child">
ChildTextContent
</div>
);
Child = HOC(Child);

输出

JavaScript
const HOC = component => component;

const Parent = () => _ref;

export default Parent;

var _ref2 = <div className="child">
ChildTextContent
</div>;

let Child = () => _ref2;
Child = HOC(Child);

var _ref = <div className="parent">
<Child />
</div>;

#5143 transform-react-constant-elements: 修复 PathHoister 提升 this 上的 JSX 成员表达式 (@STRML)

此前 <this.component /> 会被提升到其所属函数外部(这不合逻辑,否则 this 会变成 undefined

JavaScript
function render() {
this.component = "div";
return () => <this.component />;
}
JavaScript
function render() {
this.component = "div";

var _ref = <this.component />;

return () => _ref;
}

#5030 transform-do-expressions: 修复替换表达式时在循环中生成多个返回语句的问题 (@existentialism)

JavaScript
let p
let a = do {
while (p = p.parentPath) {
if (a) {
'a'
} else {
'b'
}
}
};
JavaScript
let p;
let a = function () {
var _ret;

while (p = p.parentPath) {
if (a) {
_ret = 'a';
} else {
_ret = 'b';
}
}
return _ret; // previously had an extra return
}();

#5260 babel-register: 修复缓存导致的 TypeError (@xtuc)

#5206 babel-traverse: 存在局部绑定时停止对 undefined 的求值 (@boopathi)

undefinedNaNInfinity 被重新定义,则停止优化。

#5195 babel-plugin-transform-runtime: 避免编译特定 Symbol 属性 (@taion)

不再单独引入 Symbol.asyncIterator/Symbol.observable polyfill,改为引入完整的 Symbol polyfill。

#5258 babel: 检测全局安装状态并显示正确的 CLI 提示 (@xtina-starr)

现在安装 babel 后,错误提示会正确显示是否包含 -g 参数。

#5270 babel-generator: 为 await 的三元表达式添加括号 (@erikdesjardins)

JavaScript
async function asdf() {
await (1 ? 2 : 3);
}

#5193 babel-generator: 修复模板字符串中FunctionExpression作为标签时缺失括号的问题 (@existentialism)

JavaScript
(() => {})``;
(function(){}``);

#5235 transform-es2015-modules-commonjs:限制导出节点默认赋值堆栈大小 #4323。(@mattste)

一个在导入/导出大量模块时出现的有趣问题!

JavaScript
import { foo, foo1, foo2 ... } from "foo"; // assume ... is 100 imports/exports
export { foo, foo1, foo2 ... }

生成的部分代码如下:

JavaScript
exports.Foo6 = exports.Foo5 = ...

因此当处理导出大量模块的文件时,会在AST中创建过多嵌套的赋值节点,导致代码生成器报错Maximum call stack size exceeded

解决方案是将表达式拆分为每组100个。

输出

JavaScript
exports.foo100 = undefined; // split by 100
exports.foo99 = exports.foo98 = ... exports.foo1 = exports.foo = undefined

#5255 babel-generator:使用trim替代lodash/trimEnd提升代码生成性能(@jwbay)

lodash/trimEnd会对可能庞大的字符串执行正则匹配,可能导致Node冻结。(106ms vs. 5ms)

#5050 babel-traverse:将Hub重写为接口(@yongxu)

因对babel-core的不兼容更改,此提交曾被还原

在某些场景下babel-traverse无法独立使用,此改动移除了将babel-traversebabel-core实现绑定的代码。


🌏 贡献者:20

查看 GitHub 获取完整更新日志!