From c2365bb1d72a3773b31c05feab13a96afac484df Mon Sep 17 00:00:00 2001 From: Moti Zilberman Date: Wed, 21 Sep 2022 06:38:35 -0700 Subject: [PATCH] metro-react-native-babel-preset: Remove exponentiation operator transform Summary: Context: `Math.pow(a, b)` throws when `a` or `b` is a BigInt, while `a ** b` evaluates to a BigInt in that case. This makes [`babel/plugin-transform-exponentiation-operator`](https://babeljs.io/docs/en/babel-plugin-transform-exponentiation-operator) unsafe in code that uses BigInts. See also https://github.com/facebook/react-native/issues/34656, https://github.com/facebook/react-native/issues/34603. Here we remove the plugin from the React Native Babel preset. This is safe to do because: 1. Hermes supports the `**` operator [natively](https://github.com/facebook/hermes/commit/ae0bc93f49de682c80bcd3c37b6b227dcdf262e8). 2. JSC on iOS has supported the `**` operator natively since version 10.3 (source: [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation#browser_compatibility)), and React Native targets iOS 12.4+. 3. The version of JSC React Native uses on Android ([jsc-android@v250230.2.1](https://github.com/react-native-community/jsc-android-buildscripts/releases/tag/v250230.2.1)) is based on [WebKit commit 250230](https://commits.webkit.org/250230@main) which [supports](https://github.com/WebKit/WebKit/blob/1d27863e32855c7fe51d5de1aae0589f11a428be/Source/JavaScriptCore/features.json#L170-L185) the `**` operator. 4. Metro now uses Terser as the default minifier (https://github.com/facebook/metro/pull/871) which includes support for modern language features such as the `**` operator. Changelog: * **[Fix]** Remove exponentiation operator transform from `metro-react-native-babel-preset`. NOTE: This is a fix and not a breaking change because `metro-react-native-babel-preset` is *already* meant for use only with current React Native versions, where the `**` operator is supported natively (as shown above). Reviewed By: huntie Differential Revision: D39683437 fbshipit-source-id: 67d84e7a9eecf27e40b7d7b9d4b3666a4201fec1 --- .../package.json | 1 - .../src/configs/main.js | 5 ---- packages/metro/package.json | 1 - .../integration_tests/__tests__/build-test.js | 14 +++++++++++ .../basic_bundle/TestBigInt.js | 17 ++++++++++++++ .../metro/src/integration_tests/execBundle.js | 4 ---- yarn.lock | 23 ------------------- 7 files changed, 31 insertions(+), 34 deletions(-) create mode 100644 packages/metro/src/integration_tests/basic_bundle/TestBigInt.js diff --git a/packages/metro-react-native-babel-preset/package.json b/packages/metro-react-native-babel-preset/package.json index 22fdb218cd..7c7b3da0ac 100644 --- a/packages/metro-react-native-babel-preset/package.json +++ b/packages/metro-react-native-babel-preset/package.json @@ -36,7 +36,6 @@ "@babel/plugin-transform-classes": "^7.0.0", "@babel/plugin-transform-computed-properties": "^7.0.0", "@babel/plugin-transform-destructuring": "^7.0.0", - "@babel/plugin-transform-exponentiation-operator": "^7.0.0", "@babel/plugin-transform-flow-strip-types": "^7.0.0", "@babel/plugin-transform-function-name": "^7.0.0", "@babel/plugin-transform-literals": "^7.0.0", diff --git a/packages/metro-react-native-babel-preset/src/configs/main.js b/packages/metro-react-native-babel-preset/src/configs/main.js index 8cd7734e8d..c6fd1eed48 100644 --- a/packages/metro-react-native-babel-preset/src/configs/main.js +++ b/packages/metro-react-native-babel-preset/src/configs/main.js @@ -123,11 +123,6 @@ const getPreset = (src, options) => { ]); extraPlugins.push([require('@babel/plugin-transform-async-to-generator')]); } - if (!isHermes && (isNull || src.indexOf('**') !== -1)) { - extraPlugins.push([ - require('@babel/plugin-transform-exponentiation-operator'), - ]); - } if ( isNull || src.indexOf('React.createClass') !== -1 || diff --git a/packages/metro/package.json b/packages/metro/package.json index 0747185c55..e519c5f4c6 100644 --- a/packages/metro/package.json +++ b/packages/metro/package.json @@ -67,7 +67,6 @@ }, "devDependencies": { "@babel/plugin-transform-flow-strip-types": "^7.0.0", - "acorn": "^8.7.1", "babel-jest": "^29.0.3", "dedent": "^0.7.0", "jest-snapshot": "^26.5.2", diff --git a/packages/metro/src/integration_tests/__tests__/build-test.js b/packages/metro/src/integration_tests/__tests__/build-test.js index 9aee611f0c..b2ebf04099 100644 --- a/packages/metro/src/integration_tests/__tests__/build-test.js +++ b/packages/metro/src/integration_tests/__tests__/build-test.js @@ -49,3 +49,17 @@ it('build a simple bundle with polyfills', async () => { }); expect(execBundle(result.code)).toBe('POLYFILL_IS_INJECTED'); }); + +it('builds a bundle with BigInt and exponentiation syntax', async () => { + const config = await Metro.loadConfig({ + config: require.resolve('../metro.config.js'), + }); + + const result = await Metro.runBuild(config, { + entry: 'TestBigInt.js', + }); + + // $FlowIssue[cannot-resolve-name] Flow is missing BigInt support + const BI = BigInt; + expect(execBundle(result.code)).toBe(BI(8)); +}); diff --git a/packages/metro/src/integration_tests/basic_bundle/TestBigInt.js b/packages/metro/src/integration_tests/basic_bundle/TestBigInt.js new file mode 100644 index 0000000000..290ea23a4f --- /dev/null +++ b/packages/metro/src/integration_tests/basic_bundle/TestBigInt.js @@ -0,0 +1,17 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow + */ + +'use strict'; + +// $FlowIssue[bigint-unsupported] +var a = 2n; +// $FlowIssue[bigint-unsupported] +var b = 3n; +module.exports = a ** b; diff --git a/packages/metro/src/integration_tests/execBundle.js b/packages/metro/src/integration_tests/execBundle.js index e30a1e3c8f..d84d60ad20 100644 --- a/packages/metro/src/integration_tests/execBundle.js +++ b/packages/metro/src/integration_tests/execBundle.js @@ -11,12 +11,8 @@ 'use strict'; -const acorn = require('acorn'); const vm = require('vm'); module.exports = function execBundle(code: string, context: {...} = {}): mixed { - // Verify the code can run on older VMs by parsing it as ES5 (versus ES6+). - acorn.parse(code, {ecmaVersion: 5}); - return vm.runInNewContext(code, context); }; diff --git a/yarn.lock b/yarn.lock index 5dc7521b5f..d6f832ab8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -157,14 +157,6 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc" - integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.12.13" - "@babel/types" "^7.12.13" - "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.13.8": version "7.13.16" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz#6e91dccf15e3f43e5556dffe32d860109887563c" @@ -254,13 +246,6 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== -"@babel/helper-explode-assignable-expression@^7.12.13": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f" - integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA== - dependencies: - "@babel/types" "^7.13.0" - "@babel/helper-function-name@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" @@ -844,14 +829,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-exponentiation-operator@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" - integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-transform-flow-strip-types@^7.0.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.13.0.tgz#58177a48c209971e8234e99906cb6bd1122addd3"