Page MenuHomePhabricator

[native] Add Babel plugins to transform crypto packages on React Native
ClosedPublic

Authored by ashoat on Oct 13 2024, 2:01 PM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Dec 18, 8:39 AM
Unknown Object (File)
Wed, Dec 18, 8:39 AM
Unknown Object (File)
Wed, Dec 18, 8:39 AM
Unknown Object (File)
Wed, Dec 18, 8:39 AM
Unknown Object (File)
Wed, Dec 18, 8:39 AM
Unknown Object (File)
Wed, Dec 18, 8:38 AM
Unknown Object (File)
Wed, Dec 18, 8:36 AM
Unknown Object (File)
Mon, Dec 16, 6:15 AM
Subscribers

Details

Summary

In the next diff, we add some packages that use newer JS features: BigInt literals (eg. 0n), numeric separators (eg. 1_000), and named capture groups in RegExp.

This diff adds support for those features to our Babel setup on native.

Test Plan

Tested in combination with the next diff

Diff Detail

Repository
rCOMM Comm
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

ashoat held this revision as a draft.
ashoat retitled this revision from [native] Add stuff to transform crypto packages on React Native to [native] Add Babel plugins to transform crypto packages on React Native.Oct 13 2024, 7:17 PM
ashoat edited the summary of this revision. (Show Details)
ashoat edited the test plan for this revision. (Show Details)

Add plugin-transform-named-capturing-groups-regex and reorder commits

native/.babelrc.cjs
8 ↗(On Diff #45132)

This one was the easiest. I noticed Viem was using numeric separators, so I did some quick Googling and found this Babel transform for it

10 ↗(On Diff #45132)

Viem uses named capture groups. Through some digging, I found this GitHub comment that informed me of this Babel transform that allows us to support named capture groups

patches/babel-plugin-transform-bigint+1.0.34.patch
1–738 ↗(On Diff #45132)

Our version of Hermes has a peculiar subset of BigInt supported: see here. We have most of BigInt, but no support for BigInt literals like 0n.

Babel doesn't support transforming BigInt literals to eg. BigInt(0) constructors:

Screenshot 2024-10-13 at 9.23.37 PM.png (344×1 px, 68 KB)

I think that's because they don't expect BigInt constructors to work if BigInt literals don't.

Instead, they rewrite BigInt literals to JSBI.BigInt(0) syntax, which we don't want. They also do a bunch of other transforms to get around an assumed total lack of BigInt support.

In our case, we only really want a specific transform: BigInt literals to BigInt(0) syntax.

What I'm doing here with this patch is:

  1. Removing almost the entirety of this Babel transform, as we don't need most of it. All that I left was the BigInt literal transform
  2. For the BigInt literal transform, remove the JSBI. part

Here's all that's left in node_modules/babel-plugin-transform-bigint/index.js:

// see https://github.com/babel/babel/pull/6015

const syntaxBigInt = require('@babel/plugin-syntax-bigint').default;

module.exports = function (babel) {
  const types = babel.types;
  return {
    inherits: syntaxBigInt,
    visitor: {
      BigIntLiteral: function (path, state) {
        const value = path.node.value;
        const number = Number(value); //TODO:
        if (number >= Number.MIN_SAFE_INTEGER && number <= Number.MAX_SAFE_INTEGER) {
          // 1n -> JSBI.BigInt(1)
          path.replaceWith(types.callExpression(types.identifier('BigInt'), [types.numericLiteral(number)]));
        } else {
          // 9007199254740993n -> JSBI.BigInt('9007199254740993')
          path.replaceWith(types.callExpression(types.identifier('BigInt'), [types.StringLiteral(value)]));
        }
      },
    },
  };
};
ashoat published this revision for review.Oct 13 2024, 7:40 PM
This revision is now accepted and ready to land.Oct 14 2024, 7:27 AM

One more change. I was seeing this React Native issue, and found this GitHub comment from a Metro maintainer on a separate thread. They ended up making this change upstream to resolve the issue, so in this revision I'm adding a patch to do the same thing