From 493cbe3c35cd7fc0dbad2b11029837fee54c7f32 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 28 Dec 2022 16:03:19 -0500 Subject: [PATCH 1/6] fix(NODE-XXXX): exports in package.json for react native and document how to pollyfill for BSON --- README.md | 35 +++++++++++++++++++++++++++++++++++ package.json | 6 +++--- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0e7a675e1..5ed6dd10e 100644 --- a/README.md +++ b/README.md @@ -309,6 +309,41 @@ try { } ``` +## React Native + +BSON requires `TextEncoder`, `TextDecoder`, `atob`, `btoa`, and `crypto.getRandomValues` to be available on the global object in browser-like environments. + +Since React Native has a different JS engine with different globals than either browser or Node.js has, polyfills of those APIs are required to get React Native projects working with BSON or EJSON. + +```sh +npm install --save react-native-get-random-values text-encoding-polyfill base-64 +``` + +The following snippet should be placed at the top of your index.js file for React Native projects using the BSON library. + +```typescript +// Required Polyfills For ReactNative +import {encode, decode} from 'base-64'; +if (global.btoa == null) { + global.btoa = encode; +} +if (global.atob == null) { + global.atob = decode; +} +import 'text-encoding-polyfill'; +import 'react-native-get-random-values'; +``` + +Import the BSON library like so: + +```typescript +import { BSON, EJSON } from 'bson'; +``` + +This will resolve the `node_modules/bson/lib/bson.cjs` bundle per the setting we have in the `"exports"` section of our [package.json](./package.json). + +> *Reasoning:* React Native must use the commonjs syntax version of BSON to avoid the unsupported syntax of a top-level await that is used in the es module build. + ## FAQ #### Why does `undefined` get converted to `null`? diff --git a/package.json b/package.json index 7a861a9e1..b63fe1906 100644 --- a/package.json +++ b/package.json @@ -75,11 +75,11 @@ }, "main": "./lib/bson.cjs", "module": "./lib/bson.mjs", - "browser": "./lib/bson.mjs", "exports": { - "browser": "./lib/bson.mjs", "import": "./lib/bson.mjs", - "require": "./lib/bson.cjs" + "require": "./lib/bson.cjs", + "react-native": "./lib/bson.cjs", + "browser": "./lib/bson.mjs" }, "engines": { "node": ">=14.20.1" From e08bf7844ddb88a746e53e8f25668944bbfbe0e9 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 5 Jan 2023 13:55:31 -0500 Subject: [PATCH 2/6] Update global requirements text Co-authored-by: Bailey Pearson --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 5ed6dd10e..6fc49c974 100644 --- a/README.md +++ b/README.md @@ -311,10 +311,7 @@ try { ## React Native -BSON requires `TextEncoder`, `TextDecoder`, `atob`, `btoa`, and `crypto.getRandomValues` to be available on the global object in browser-like environments. - -Since React Native has a different JS engine with different globals than either browser or Node.js has, polyfills of those APIs are required to get React Native projects working with BSON or EJSON. - +BSON requires that `TextEncoder`, `TextDecoder`, `atob`, `btoa`, and `crypto.getRandomValues` are available globally. These are present in most Javascript runtimes but require polyfilling in React Native. Polyfills for the missing functionality can be installed with the following command: ```sh npm install --save react-native-get-random-values text-encoding-polyfill base-64 ``` From 5cefe2f5f1833c5de3c1b9c152b650839aa584b9 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 5 Jan 2023 13:56:26 -0500 Subject: [PATCH 3/6] Update where to put polyfills Co-authored-by: Bailey Pearson --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6fc49c974..167f99326 100644 --- a/README.md +++ b/README.md @@ -316,7 +316,7 @@ BSON requires that `TextEncoder`, `TextDecoder`, `atob`, `btoa`, and `crypto.get npm install --save react-native-get-random-values text-encoding-polyfill base-64 ``` -The following snippet should be placed at the top of your index.js file for React Native projects using the BSON library. +The following snippet should be placed at the top of the entrypoint (by default this is the root `index.js` file) for React Native projects using the BSON library. These lines must be placed for any code that imports `BSON`. ```typescript // Required Polyfills For ReactNative From a84c658e982833d607e435d982d298260f6f046e Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 5 Jan 2023 13:56:56 -0500 Subject: [PATCH 4/6] nit fix text Co-authored-by: Bailey Pearson --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 167f99326..c793894d7 100644 --- a/README.md +++ b/README.md @@ -331,7 +331,7 @@ import 'text-encoding-polyfill'; import 'react-native-get-random-values'; ``` -Import the BSON library like so: +Finally, import the `BSON` library like so: ```typescript import { BSON, EJSON } from 'bson'; From c85cea4bd58f7c827c8c3f16f12851ded967b911 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 5 Jan 2023 14:49:54 -0500 Subject: [PATCH 5/6] Add clarity to the technical details of the react native import --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c793894d7..0781a2a6d 100644 --- a/README.md +++ b/README.md @@ -339,7 +339,9 @@ import { BSON, EJSON } from 'bson'; This will resolve the `node_modules/bson/lib/bson.cjs` bundle per the setting we have in the `"exports"` section of our [package.json](./package.json). -> *Reasoning:* React Native must use the commonjs syntax version of BSON to avoid the unsupported syntax of a top-level await that is used in the es module build. +### Technical Note about React Native module import + +The `"exports"` definition in our `package.json` will result in BSON's CommonJS bundle being imported in a React Native project instead of the ES module bundle. Importing the CommonJS bundle is necessary because BSON's ES module bundle of BSON uses top-level await, which is not supported syntax in [React Native's runtime hermes](https://hermesengine.dev/). ## FAQ From dff0028f3da54030a20f9d6617613a1d983f2e46 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 5 Jan 2023 15:01:43 -0500 Subject: [PATCH 6/6] Update README.md Co-authored-by: Bailey Pearson --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0781a2a6d..a83d56226 100644 --- a/README.md +++ b/README.md @@ -337,7 +337,7 @@ Finally, import the `BSON` library like so: import { BSON, EJSON } from 'bson'; ``` -This will resolve the `node_modules/bson/lib/bson.cjs` bundle per the setting we have in the `"exports"` section of our [package.json](./package.json). +This will cause React Native to import the `node_modules/bson/lib/bson.cjs` bundle (see the `"react-native"` setting we have in the `"exports"` section of our [package.json](./package.json).) ### Technical Note about React Native module import