BREAKING CHANGE: UPGRADE REACT NATIVE TO BABEL 7!

Summary:
BREAKING CHANGE
This change upgrades the React Native build pipeline from Babel 6 to Babel 7

If you use a `.babelrc` then you'll need to update it to Babel 7 (note that some plugins are no longer relevant, some plugins are automatically upgraded, and some will need some manual love).

Note that you may also need to upgrade your dev env, tests etc, to make sure they work with Babel 7.

Reviewed By: mjesun

Differential Revision: D7591303

fbshipit-source-id: 29cef21f6466633a9c366d1f3c0d3cf874c714db
This commit is contained in:
Peter van der Zee 2018-04-11 16:29:36 -07:00 committed by Facebook Github Bot
parent 3277bed1f8
commit f8d6b97140
3 changed files with 234 additions and 113 deletions

View File

@ -12,19 +12,15 @@
/* eslint-disable quotes, curly, no-proto, no-undef-init, dot-notation */
// Created by running:
// require('babel-core').buildExternalHelpers('_extends classCallCheck createClass createRawReactElement defineProperty get inherits interopRequireDefault interopRequireWildcard objectWithoutProperties possibleConstructorReturn slicedToArray taggedTemplateLiteral toArray toConsumableArray '.split(' '))
// then replacing the `global` reference in the last line to also use `this`.
// require('fs').writeFileSync('babelExternalHelpers.js', require('@babel/core').buildExternalHelpers('_extends classCallCheck createClass createRawReactElement defineProperty get inherits interopRequireDefault interopRequireWildcard objectWithoutProperties possibleConstructorReturn slicedToArray taggedTemplateLiteral toArray toConsumableArray wrapNativeSuper assertThisInitialized taggedTemplateLiteralLoose'.split(' ')))// then replacing the `global` reference in the last line to also use `this`.
//
// actually, that's a lie, because babel6 omits _extends and createRawReactElement
// Actually, that's a lie, because babel omits _extends and
// createRawReactElement. the file is also cleaned up a bit.
// You may need to clear wrapNativeSuper while the bug hasn't been fixed yet.
// Do try to keep diffs to a minimum.
var babelHelpers = global.babelHelpers = {};
babelHelpers.typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
babelHelpers.createRawReactElement = (function () {
var REACT_ELEMENT_TYPE = typeof Symbol === "function" && Symbol.for && Symbol.for("react.element") || 0xeac7;
return function createRawReactElement(type, key, props) {
@ -45,8 +41,7 @@ babelHelpers.classCallCheck = function (instance, Constructor) {
}
};
babelHelpers.createClass = (function () {
function defineProperties(target, props) {
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
@ -56,22 +51,11 @@ babelHelpers.createClass = (function () {
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
babelHelpers.createClass = function(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
};
})();
babelHelpers.defineEnumerableProperties = function(obj, descs) {
for (var key in descs) {
var desc = descs[key];
desc.configurable = (desc.enumerable = true);
if ('value' in desc) desc.writable = true;
Object.defineProperty(obj, key, desc);
}
return obj;
};
babelHelpers.defineProperty = function (obj, key, value) {
if (key in obj) {
@ -129,9 +113,8 @@ babelHelpers.get = function get(object, property, receiver) {
babelHelpers.inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
@ -143,6 +126,54 @@ babelHelpers.inherits = function (subClass, superClass) {
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var _gPO = Object.getPrototypeOf || function _gPO(o) { return o.__proto__ };
var _sPO = Object.setPrototypeOf || function _sPO(o, p) { o.__proto__ = p; return o };
var _construct =
// TODO: prepack does not like this line (and we can use the fallback just fine)
// (typeof Reflect === "object" && Reflect.construct) ||
function _construct(Parent, args, Class) {
var Constructor, a = [null];
a.push.apply(a, args);
Constructor = Parent.bind.apply(Parent, a);
return _sPO(new Constructor, Class.prototype);
};
var _cache = typeof Map === "function" && new Map();
babelHelpers.wrapNativeSuper = function(Class) {
// FB:
// Note: while extending native classes is pretty meh we do have cases, for
// example; Error. There is also a false positive, for example; Blob.
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
// this is a temporary fix for a babel bug (it's invoking the wrong func
// when you do `super()`)
return _construct(Class, arguments, _gPO(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writeable: true,
configurable: true,
}
});
return _sPO(
Wrapper,
_sPO(
function Super() {
return _construct(Class, arguments, _gPO(this).constructor);
},
Class
)
);
};
babelHelpers.interopRequireDefault = function (obj) {
return obj && obj.__esModule ? obj : {
default: obj
@ -157,7 +188,15 @@ babelHelpers.interopRequireWildcard = function (obj) {
if (obj != null) {
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
if (desc.get || desc.set) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
}
@ -166,28 +205,45 @@ babelHelpers.interopRequireWildcard = function (obj) {
}
};
babelHelpers.objectWithoutProperties = function (obj, keys) {
babelHelpers.objectWithoutProperties = function(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (var i in obj) {
if (keys.indexOf(i) >= 0) continue;
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
target[i] = obj[i];
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for (i = 0; i < sourceSymbolKeys.length; i++) {
key = sourceSymbolKeys[i];
if (excluded.indexOf(key) >= 0) continue;
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
target[key] = source[key];
}
}
return target;
};
babelHelpers.possibleConstructorReturn = function (self, call) {
if (!self) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
return self;
};
babelHelpers.slicedToArray = (function () {
function sliceIterator(arr, i) {
function _sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
@ -204,7 +260,7 @@ babelHelpers.slicedToArray = (function () {
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
@ -213,16 +269,15 @@ babelHelpers.slicedToArray = (function () {
return _arr;
}
return function (arr, i) {
babelHelpers.slicedToArray = function(arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
return _sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
})();
babelHelpers.taggedTemplateLiteral = function (strings, raw) {
return Object.freeze(Object.defineProperties(strings, {
@ -238,10 +293,25 @@ babelHelpers.toArray = function (arr) {
babelHelpers.toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
};
babelHelpers.assertThisInitialized = function(self) {
if (self === void 0) {
throw new ReferenceError(
"this hasn't been initialised - super() hasn't been called",
);
}
return self;
};
babelHelpers.taggedTemplateLiteralLoose = function(strings, raw) {
strings.raw = raw;
return strings;
};

View File

@ -8,37 +8,55 @@
'use strict';
const defaultPlugins = [
[require('babel-plugin-syntax-class-properties')],
[require('babel-plugin-syntax-trailing-function-commas')],
[require('babel-plugin-transform-class-properties')],
[require('babel-plugin-transform-es2015-block-scoping')],
[require('babel-plugin-transform-es2015-computed-properties')],
[require('babel-plugin-transform-es2015-destructuring')],
[require('babel-plugin-transform-es2015-function-name')],
[require('babel-plugin-transform-es2015-literals')],
[require('babel-plugin-transform-es2015-parameters')],
[require('babel-plugin-transform-es2015-shorthand-properties')],
[require('babel-plugin-transform-flow-strip-types')],
[require('babel-plugin-transform-react-jsx')],
[require('babel-plugin-transform-regenerator')],
[require('@babel/plugin-transform-block-scoping')],
// the flow strip types plugin must go BEFORE class properties!
// there'll be a test case that fails if you don't.
[require('@babel/plugin-transform-flow-strip-types')],
[
require('babel-plugin-transform-es2015-modules-commonjs'),
{strict: false, allowTopLevelThis: true},
require('@babel/plugin-proposal-class-properties'),
// use `this.foo = bar` instead of `this.defineProperty('foo', ...)`
// (Makes the properties enumerable)
{loose: true},
],
[require('@babel/plugin-transform-computed-properties')],
[require('@babel/plugin-transform-destructuring')],
[require('@babel/plugin-transform-function-name')],
[require('@babel/plugin-transform-literals')],
[require('@babel/plugin-transform-parameters')],
[require('@babel/plugin-transform-shorthand-properties')],
[require('@babel/plugin-transform-react-jsx')],
[require('@babel/plugin-transform-regenerator')],
[require('@babel/plugin-transform-sticky-regex')],
[require('@babel/plugin-transform-unicode-regex')],
[
require('@babel/plugin-transform-modules-commonjs'),
{
strict: false,
strictMode : false, // prevent "use strict" injections
allowTopLevelThis: true, // dont rewrite global `this` -> `undefined`
},
],
];
const checkES2015Constants = [require('babel-plugin-check-es2015-constants')];
const es2015ArrowFunctions = [require('babel-plugin-transform-es2015-arrow-functions')];
const es2015Classes = [require('babel-plugin-transform-es2015-classes')];
const es2015ForOf = [require('babel-plugin-transform-es2015-for-of'), {loose: true}];
const es2015Spread = [require('babel-plugin-transform-es2015-spread')];
const es2015TemplateLiterals = [require('babel-plugin-transform-es2015-template-literals')];
const asyncFunctions = [require('babel-plugin-syntax-async-functions')];
const exponentiationOperator = [require('babel-plugin-transform-exponentiation-operator')];
const objectAssign = [require('babel-plugin-transform-object-assign')];
const objectRestSpread = [require('babel-plugin-transform-object-rest-spread')];
const reactDisplayName = [require('babel-plugin-transform-react-display-name')];
const reactJsxSource = [require('babel-plugin-transform-react-jsx-source')];
const es2015ArrowFunctions = [
require('@babel/plugin-transform-arrow-functions'),
];
const es2015Classes = [require('@babel/plugin-transform-classes')];
const es2015ForOf = [require('@babel/plugin-transform-for-of'), {loose: true}];
const es2015Spread = [require('@babel/plugin-transform-spread')];
const es2015TemplateLiterals = [
require('@babel/plugin-transform-template-literals'),
{loose: true}, // dont 'a'.concat('b'), just use 'a'+'b'
];
const exponentiationOperator = [
require('@babel/plugin-transform-exponentiation-operator'),
];
const objectAssign = [require('@babel/plugin-transform-object-assign')];
const objectRestSpread = [require('@babel/plugin-proposal-object-rest-spread')];
const reactDisplayName = [
require('@babel/plugin-transform-react-display-name'),
];
const reactJsxSource = [require('@babel/plugin-transform-react-jsx-source')];
const symbolMember = [require('../transforms/transform-symbol-member')];
const getPreset = (src, options) => {
@ -49,18 +67,12 @@ const getPreset = (src, options) => {
const extraPlugins = [];
if (isNull || src.indexOf('async') !== -1 || src.indexOf('await') !== -1) {
extraPlugins.push(asyncFunctions);
}
if (hasClass) {
extraPlugins.push(es2015Classes);
}
if (isNull || src.indexOf('=>') !== -1) {
extraPlugins.push(es2015ArrowFunctions);
}
if (isNull || src.indexOf('const') !== -1) {
extraPlugins.push(checkES2015Constants);
}
if (isNull || hasClass || src.indexOf('...') !== -1) {
extraPlugins.push(es2015Spread);
extraPlugins.push(objectRestSpread);

View File

@ -11,7 +11,7 @@
'use strict';
const babel = require('babel-core');
const {transformSync: babelTransformSync} = require('@babel/core');
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
* found when Flow v0.54 was deployed. To see the error delete this comment and
* run Flow. */
@ -20,7 +20,7 @@ const babelRegisterOnly = require('metro/src/babelRegisterOnly');
* found when Flow v0.54 was deployed. To see the error delete this comment and
* run Flow. */
const createCacheKeyFunction = require('fbjs-scripts/jest/createCacheKeyFunction');
const generate = require('babel-generator').default;
const generate = require('@babel/generator').default;
const nodeFiles = RegExp([
'/local-cli/',
@ -35,7 +35,7 @@ const transformer = require('metro/src/transformer.js');
module.exports = {
process(src/*: string*/, file/*: string*/) {
if (nodeFiles.test(file)) { // node specific transforms only
return babel.transform(
return babelTransformSync(
src,
Object.assign({filename: file}, nodeOptions)
).code;
@ -54,6 +54,45 @@ module.exports = {
retainLines: true,
},
src,
plugins: [
[require('@babel/plugin-transform-block-scoping')],
// the flow strip types plugin must go BEFORE class properties!
// there'll be a test case that fails if you don't.
[require('@babel/plugin-transform-flow-strip-types')],
[
require('@babel/plugin-proposal-class-properties'),
// use `this.foo = bar` instead of `this.defineProperty('foo', ...)`
// (Makes the properties enumerable)
{loose: true},
],
[require('@babel/plugin-transform-computed-properties')],
[require('@babel/plugin-transform-destructuring')],
[require('@babel/plugin-transform-function-name')],
[require('@babel/plugin-transform-literals')],
[require('@babel/plugin-transform-parameters')],
[require('@babel/plugin-transform-shorthand-properties')],
[require('@babel/plugin-transform-react-jsx')],
[require('@babel/plugin-transform-regenerator')],
[require('@babel/plugin-transform-sticky-regex')],
[require('@babel/plugin-transform-unicode-regex')],
[
require('@babel/plugin-transform-modules-commonjs'),
{strict: false, allowTopLevelThis: true},
],
[require('@babel/plugin-transform-classes')],
[require('@babel/plugin-transform-arrow-functions')],
[require('@babel/plugin-transform-spread')],
[require('@babel/plugin-proposal-object-rest-spread')],
[
require('@babel/plugin-transform-template-literals'),
{loose: true}, // dont 'a'.concat('b'), just use 'a'+'b'
],
[require('@babel/plugin-transform-exponentiation-operator')],
[require('@babel/plugin-transform-object-assign')],
[require('@babel/plugin-transform-for-of'), {loose: true}],
[require('@babel/plugin-transform-react-display-name')],
[require('@babel/plugin-transform-react-jsx-source')],
],
});
return generate(ast, {
@ -70,6 +109,6 @@ module.exports = {
getCacheKey: createCacheKeyFunction([
__filename,
require.resolve('metro/src/transformer.js'),
require.resolve('babel-core/package.json'),
require.resolve('@babel/core/package.json'),
]),
};