ai / nanoid

A tiny (124 bytes), secure, URL-friendly, unique string ID generator for JavaScript

Home Page:https://zelark.github.io/nano-id-cc/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Not working with expo

2ico opened this issue · comments

commented

Expo SDK: 49.0.0
After following the instructions at https://github.com/ai/nanoid#react-native , I get:

Android Bundling failed 403ms
The package at "node_modules/nanoid/index.js" attempted to import the Node standard library module "node:crypto".
It failed because the native React runtime does not include the Node standard library.
commented

Yes, I did

Sorry, I have no idea or experience with Expo.

Try to ask Expo community.

commented

I think the issue is here:
https://github.com/ai/nanoid/blob/61a087715a21d971dc9154c5726c818db0e42b27/index.js#L1C1-L1C50
The module imports the entire webCrypto from node:crypto.

In version 3 only the required function getRandomBytesAsync was imported:

let { getRandomBytesAsync } = require('expo-random')

Nope, those are different files. Sync and async.

commented

Async was removed in v5, right?

commented

So what is the status for expo compatibility?
I see someone was using expo here: #415

Yes, it should work. This doc was written by Expo user.

commented

Can I contact them?

I don’t think it is polite. You should use StackOverflow and similar things if you want ask others to do your work.

Try also import index.browser.js version. Maybe react-native-get-random-values polyfill has issue with import.

commented

I don't think it's impolite to contact the maintainer of a library.

I am the maintainer. You want to contact some other developer who send PR to the library.

commented

Anyway, how can I do this?

Try also import index.browser.js version. Maybe react-native-get-random-values polyfill has issue with import.

Could not find a declaration file for module 'nanoid/index.browser'. '/home/george/Documents/GAIO/expo/archie-expo/node_modules/nanoid/index.browser.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/nanoid` if it exists or add a new declaration (.d.ts) file containing `declare module 'nanoid/index.browser';`

This is just a type warning not an error.

Does it works?

commented

It works, with @ts-ignore

Try the new Nano ID 5.0.6 with normal import { nanoid } from 'nanoid

commented

It doesn't work, unfortunately. It's still using './index.js'.
Thanks for the quick attempt!

commented

And I guess the release should include a ./index.browser.d.ts file to solve the error I got with TS.

And I guess the release should include a ./index.browser.d.ts file to solve the error I got with TS.

Separeted manual import for browser version is not a long-term solution because you can't change import inside other libraries.

It was only a test.

I tried this patch but without a success

diff --git a/package.json b/package.json
index 0d10ada4dce6c02a339399e71c82860c70f3d12b..4fb2ab8de9093eae1bc590cd738019e5b40d0dfb 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
   "exports": {
     ".": {
       "browser": "./index.browser.js",
+      "react-native": "./index.browser.js",
       "default": "./index.js"
     },
     "./non-secure": "./non-secure/index.js",

Why RN doesn't pick browser.js is a mystery.

In case anyone is still running into this and this is helpful. We had this problem and had to do 2 separate things to get crypto resolved correctly in different situations:

  1. We had to do the metro.config.js adjustment to properly resolve the module in case it was being explicitly imported:
config.resolver.resolveRequest = (context, moduleName, platform) => {
  if (moduleName === 'crypto' || moduleName === 'node:crypto') {
    // when importing crypto, resolve to react-native-quick-crypto
    return context.resolveRequest(context, 'react-native-quick-crypto', platform);
  }
  // otherwise chain to the standard Metro resolver.
  return context.resolveRequest(context, moduleName, platform);
};

(note, we added the node:crypto clause in case it mattered for some imports, although we never confirmed this was helpful for any particular case.

  1. We also had to override global.crypto since index.browser.js was being imported by default in our case
import { install } from 'react-native-quick-crypto';
install();

With both of these, we covered all our bases