ai / nanoid

A tiny (124 bytes), secure, URL-friendly, unique string ID generator for JavaScript
https://zelark.github.io/nano-id-cc/
MIT License
24.22k stars 790 forks source link

Not working with expo #468

Open 2ico opened 6 months ago

2ico commented 6 months ago

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.
ai commented 6 months ago

Did you foolow that steps?

https://github.com/ai/nanoid?tab=readme-ov-file#react-native

2ico commented 6 months ago

Yes, I did

ai commented 6 months ago

Sorry, I have no idea or experience with Expo.

Try to ask Expo community.

2ico commented 6 months ago

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: https://github.com/ai/nanoid/blob/89d82d2ce4b0411e73ac7ccfe57bc03e932416e2/async/index.native.js#L1

ai commented 6 months ago

Nope, those are different files. Sync and async.

2ico commented 6 months ago

Async was removed in v5, right?

ai commented 6 months ago

Yes

2ico commented 6 months ago

So what is the status for expo compatibility? I see someone was using expo here: https://github.com/ai/nanoid/pull/415

ai commented 6 months ago

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

2ico commented 6 months ago

Can I contact them?

ai commented 6 months ago

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.

2ico commented 6 months ago

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

ai commented 6 months ago

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

2ico commented 6 months ago

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';`
ai commented 6 months ago

This is just a type warning not an error.

Does it works?

2ico commented 6 months ago

It works, with @ts-ignore

ai commented 6 months ago

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

2ico commented 6 months ago

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

2ico commented 6 months ago

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

ai commented 6 months ago

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.

steida commented 4 months ago

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.

danielsht86 commented 2 months ago

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.

  2. 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