Created by: eps1lon
Fixes unoptimized destructuring when used with @babel/preset-env
Before:
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MyComponent = MyComponent;
var _react = _interopRequireDefault(require("react"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
var __reactCreateElement__ = _react["default"].createElement;
var useState = _react["default"].useState;
function MyComponent() {
var _useState = useState(0),
_useState2 = _slicedToArray(_useState, 2),
counter = _useState2[0],
setCounter = _useState2[1];
return __reactCreateElement__("div", null, counter);
}
After:
""use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MyComponent = MyComponent;
var _react = _interopRequireDefault(require("react"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var __reactCreateElement__ = _react.default.createElement;
var useState = _react.default.useState;
function MyComponent() {
var _ref_ = useState(0);
var setCounter = _ref_[1];
var counter = _ref_[0];
return __reactCreateElement__("div", null, counter);
}
The problem is how babel runs plugins. While it does run plugins before presets it only does so per node. Since plugins are applied while traversing down (guess) and transform-destructuring
runs on VariableDeclaration
transform-destructuring
is applied before optimize-react
(which runs on CallExpression
which is a child in the targetted ASTs). By moving optimize-react
to the same level as transform-destructuring
we can guarantee for this plugin that the plugin is applied before the preset.
This change includes using scope.generateUidIdentifier
instead of handcrafting an identifier from state. Even if the fix is rejected this refactoring should be considered since it is technically possible to create variable collisions with the previous approach.