Prior to this change, we'd conduct an open-ended traversal on the 'id' of any VariableDeclarator to find a RestElement. The 'id' of a VariableDeclarator can contain an AssignmentPattern (to supply a default value), and if the right-hand side of the AssignmentPattern contained a RestElement, we'd transform it. The problem here is that the right-hand side of an AssignmentPattern can be *any* Expression. If the right-hand side is a function body, we'd traverse the entire function body, and if a RestElement occurred anywhere in that function body, we'd transform it and emit the transformations wherever we began the traversal (at least one scope outside its usage). The fix is to stop the inner traversal if we encounter an AssignmentPattern. The outer traversal will still visit the AssignmentPattern, so RestElements within the right-hand side of an AssignmentPattern will be properly transformed at that time.
@babel/plugin-proposal-object-rest-spread
This plugin allows Babel to transform rest properties for object destructuring assignment and spread properties for object literals.
Example
Rest Properties
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
console.log(x); // 1
console.log(y); // 2
console.log(z); // { a: 3, b: 4 }
Spread Properties
let n = { x, y, ...z };
console.log(n); // { x: 1, y: 2, a: 3, b: 4 }
Installation
npm install --save-dev @babel/plugin-proposal-object-rest-spread
Usage
Via .babelrc (Recommended)
.babelrc
{
"plugins": ["@babel/plugin-proposal-object-rest-spread"]
}
Via CLI
babel --plugins @babel/plugin-proposal-object-rest-spread script.js
Via Node API
require("@babel/core").transform("code", {
plugins: ["@babel/plugin-proposal-object-rest-spread"]
});
Options
By default, this plugin will produce spec compliant code. The Babel's objectSpread helper will be used.
loose
boolean, defaults to false.
Enabling this option will use Babel's extends helper, which is basically the same as Object.assign (see useBuiltIns below to use it directly).
⚠️ Please take in mind that even if they're almost equivalent, there's an important difference between spread and Object.assign: to summarize, spread defines new properties, while Object.assign() sets them, so using this mode might produce unexpected results in some case.
For detailed information please check out Spread VS. Object.assign and Assigning VS. defining properties.
useBuiltIns
boolean, defaults to false.
Enabling this option will use Object.assign directly instead of the Babel's extends helper. Keep in mind that this flag only applies when loose: true.
Example
.babelrc
{
"plugins": [
["@babel/plugin-proposal-object-rest-spread", { "loose": true, "useBuiltIns": true }]
]
}
In
z = { x, ...y };
Out
z = Object.assign({ x }, y);