supabase-js icon indicating copy to clipboard operation
supabase-js copied to clipboard

Can't use with unstable_enablePackageExports metro option (expo)

Open aldebout opened this issue 1 year ago • 22 comments
trafficstars

Cross-posting https://github.com/supabase/realtime-js/issues/415 because I'm not sure you're monitoring the issues on the other repo :)

Bug report

  • [x] I confirm this is a bug with Supabase, not with my own application.
  • [x] I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

When using @supabase/supabase-js in an expo react native project, if I use the unstable_enablePackageExports with the metro bundler, bundling fails with the following error:

To Reproduce

  1. Generate a new expo app
  2. Add @supabase/supabase-js as a dependency
  3. Create a supabase client in the main _layout.tsx file
  4. Run npx expo customize metro.config.js
  5. Add config.resolver.unstable_enablePackageExports = true; to metro.config.js
  6. Add ios.bundleIdentifier to app.json
  7. Run npx expo run:ios

Repro repo: https://github.com/aldebout/supabase-expo-exports-issue

Expected behavior

No crash

Screenshots

image

System information

  • OS: macOS
  • Version of supabase-js: 2.45.1
  • Version of Node.js: 20.16.0

Additional information

Opening here because the error message I got in my actual project was

The package at "../../node_modules/@supabase/realtime-js/node_modules/ws/lib/stream.js" attempted to import the Node standard library module "stream".
It failed because the native React runtime does not include the Node standard library.

aldebout avatar Aug 16 '24 11:08 aldebout

Is there any update on this? I've run into the same issue

practiv-wamci avatar Sep 11 '24 01:09 practiv-wamci

I've also run into this when trying to use Storybook and Expo.

adamwett avatar Oct 12 '24 03:10 adamwett

I'm able to run it by manually specifying nodeModulesPaths and setting disableHierarchicalLookup to true (in a monorepo setup).

marcocondrache avatar Oct 29 '24 17:10 marcocondrache

I'm able to run it by manually specifying nodeModulesPaths and setting disableHierarchicalLookup to true (in a monorepo setup).

This solution didn't work for me

I was able to fix it by patching @supabase/realtime-js to match supabase/realtime-js#426

patchfile looks like this

diff --git a/dist/module/RealtimeClient.js b/dist/module/RealtimeClient.js
index a8bb0121343481d789acb0248ecbb20c7e4597fe..a299d5b3370b836bdf28307deb7a157c6ccf0bc5 100644
--- a/dist/module/RealtimeClient.js
+++ b/dist/module/RealtimeClient.js
@@ -143,12 +143,6 @@ export default class RealtimeClient {
                 this.conn = null;
             },
         });
-        import('ws').then(({ default: WS }) => {
-            this.conn = new WS(this._endPointURL(), undefined, {
-                headers: this.headers,
-            });
-            this.setupConnection();
-        });
     }
     /**
      * Disconnects the socket.

named patches/@supabase__realtime-js.patch

I then added the following to my package.json (for pnpm)

  "pnpm": {
    "patchedDependencies": {
      "@supabase/realtime-js": "patches/@supabase__realtime-js.patch"
    },
    "overrides": {
      "@supabase/realtime-js>ws": "-" 
    }
  }

DanielVolchek avatar Nov 28 '24 03:11 DanielVolchek

I've merged https://github.com/supabase/realtime-js/pull/444 so 2.11.4-next.1 will have this code.

I do need some help testing this change, if possible do override realtime-js in supabase-js with this version

filipecabaco avatar Dec 11 '24 14:12 filipecabaco

Unfortunately doesn't seem to be working

Screenshot 2024-12-11 at 12 00 08 PM

Can also confirm that the package is overriden correctly Screenshot 2024-12-11 at 12 01 28 PM

DanielVolchek avatar Dec 11 '24 20:12 DanielVolchek

so this is happening during the bundling process of Expo, is there a way to configure which package to remove from the bundling process in some sort of configuration?

filipecabaco avatar Dec 11 '24 21:12 filipecabaco

Not sure about expo but with pnpm I can do this and it works

  "pnpm": {
    "overrides": {
      "@supabase/realtime-js": "2.11.4-next.1",
      "@supabase/realtime-js>ws": "-"
    }
  }

DanielVolchek avatar Dec 11 '24 21:12 DanielVolchek

I need to double check why we need the ws library 🤔

filipecabaco avatar Dec 12 '24 11:12 filipecabaco

Same issue here.

 ERROR  [Error: undefined Unable to resolve module stream from /Users/gianpaj/tmp/call-me-please/node_modules/ws/lib/stream.js: stream could not be found within the project or in these directories:
  ../../node_modules
  ../../../node_modules
  node_modules
  ../../node_modules
  1 | 'use strict';
  2 |
> 3 | const { Duplex } = require('stream');
    |                             ^
  4 |
  5 | /**
  6 |  * Emits the `'close'` event on a stream.]
The package at "node_modules/ws/lib/stream.js" attempted to import the Node standard library module "stream".
It failed because the native React runtime does not include the Node standard library.

the code is open sourced here: https://github.com/gianpaj/call-me-please

If you uncomment the supabase import and the Signup <Button/> in the settings.tsx file, you'll see the same error message

$ pnpm list --depth 1 | grep supabase
@supabase/supabase-js 2.47.10
├── @supabase/auth-js 2.67.3
├── @supabase/functions-js 2.4.4
├── @supabase/node-fetch 2.6.15
├── @supabase/postgrest-js 1.17.7
├── @supabase/realtime-js 2.11.2
└── @supabase/storage-js 2.7.1

$ pnpm list --depth 0 | grep expo
@expo/metro-config 0.19.8
expo 52.0.23

Overwriting to 2.11.4-next.1 of @supabase/realtime-js didn't work either :(

This is the metro.config.js file for Turborepo mono repo setup https://github.com/gianpaj/call-me-please/blob/master/apps/expo/metro.config.js

gianpaj avatar Jan 05 '25 13:01 gianpaj

Any update? I can't get past this issue as other parts of my project need unstable_enablePackageExports: true.

aimachinedream avatar Jan 18 '25 02:01 aimachinedream

@filipecabaco any updates?

xStrixU avatar Jan 20 '25 19:01 xStrixU

Has it been solved? couldnt find anything

Francowerner avatar Jan 28 '25 19:01 Francowerner

not yet unfortunately as removing ws package has proven not to be enough ... any other clue on what it could help?

filipecabaco avatar Jan 28 '25 20:01 filipecabaco

So far the only thing that worked was setting unstable_enablePackageExports to false, though i dont know what consequences it could have on my project. Im currently using create-t3-turbo but with expo 52, and it got it to work but now nativewind has broken.

Francowerner avatar Jan 28 '25 20:01 Francowerner

So far the only thing that worked was setting unstable_enablePackageExports to false, though i dont know what consequences it could have on my project. Im currently using create-t3-turbo but with expo 52, and it got it to work but now nativewind has broken.

Doing this in a monorepo breaks the import of packages in the monorepo: Unable to resolve "@acme/shared/utils" from "apps/expo/src/app/profile.tsx"

For the tailwind thing probably just update it, also update the react-native-css-interop package.

I've tried everything mentioned in here but haven't figured how to make it work. I've got another repo where its working but its much simpler, haven't figured out what breaks it as both are based on the create-t3-turbo example

monopolo11 avatar Jan 30 '25 02:01 monopolo11

So far the only thing that worked was setting unstable_enablePackageExports to false, though i dont know what consequences it could have on my project. Im currently using create-t3-turbo but with expo 52, and it got it to work but now nativewind has broken.

Doing this in a monorepo breaks the import of packages in the monorepo: Unable to resolve "@acme/shared/utils" from "apps/expo/src/app/profile.tsx"

For the tailwind thing probably just update it, also update the react-native-css-interop package.

I've tried everything mentioned in here but haven't figured how to make it work. I've got another repo where its working but its much simpler, haven't figured out what breaks it as both are based on the create-t3-turbo example

I have updates regarding the nativewind issue. Turns out it was another dependecy called react native reusables which created a tailwind.config.js file when the monorepo already uses a tailwind.config.ts file on apps/expo, so its was just a matter of merging those configs and it worked.

On the other hand, i unfortunately had to uninstall supabase since expo 52 wont compile at all. Have you tried cloning a fresh copy of create-t3-turbo (Julius just updated some packages like expo and more recently) and installing just supabase to see if it even runs? i swear, nextauth is just the worst thing ever even if somehow you manage to get it working, it just finds a way to f with you every time. Im desperate to try supabase auth on my app.

To be fair, when i set unstable_enablePackageExports to false it did not cause the Unable to resolve "@acme/shared/utils" from "apps/expo/src/app/profile.tsx" you mention. It may do so after u get past the supabase error, i dont really know though. I found some other metro config you could pull to allow expo to manually (as in, you have to write the aliases for each one u want) access your monorepo packages, which i alledge would fix your issue.

Francowerner avatar Jan 30 '25 14:01 Francowerner

New update: I got it to work out of the box!

Clone the latest version of create-t3-turbo, follow the tutorial at https://supabase.com/docs/guides/getting-started/tutorials/with-expo-react-native?queryGroups=auth-store&auth-store=async-storage to do the supabase setup and it'll work. Tried it twice and no metro issues, no nothing and without having to set unstable_enablePackageExports to false

Just in case do a pnpm dlx expo prebuild --clean first then pnpm ios or pnpm android . I'd also advise you make sure to edit the start script as follows "dev": "expo start --clear" so you dont run into cache issues.

So far i've only tried supabase auth but will update this when i try realtime and other supabase products.

If you dont work in a monorepo you can just follow how expo is set up at apps/expo and it'll work too.

Francowerner avatar Jan 30 '25 15:01 Francowerner

New update: I got it to work out of the box!

Clone the latest version of create-t3-turbo, follow the tutorial at https://supabase.com/docs/guides/getting-started/tutorials/with-expo-react-native?queryGroups=auth-store&auth-store=async-storage to do the supabase setup and it'll work. Tried it twice and no metro issues, no nothing and without having to set unstable_enablePackageExports to false

Just in case do a pnpm dlx expo prebuild --clean first then pnpm ios or pnpm android . I'd also advise you make sure to edit the start script as follows "dev": "expo start --clear" so you dont run into cache issues.

So far i've only tried supabase auth but will update this when i try realtime and other supabase products.

If you dont work in a monorepo you can just follow how expo is set up at apps/expo and it'll work too.

This didn't work out for me, tried it by cloning it and following the guide you provided and haven't been able to get it working.

monopolo11 avatar Feb 02 '25 03:02 monopolo11

This fixed the issues I've been having:

config.resolver.unstable_conditionNames = ['require', 'default', 'browser']. For me, adding 'browser' has fixed it so far.

IamJoshing avatar Feb 18 '25 01:02 IamJoshing

Sorry for the radio silence on my side.

@IamJoshing is there a explicit explanation why this works? it could help us understand what we need to change in realtime-js to properly fix it.

filipecabaco avatar Feb 18 '25 11:02 filipecabaco

I have no idea. I tried it after everything else had failed. I found some other examples of metro configs on the Expo Discord with more condition names. I added in the condition names that I didn't have. It worked. Then I removed them individually until I knew it was 'browser'. If this works for others, maybe someone at Expo can give you an answer as to why.

IamJoshing avatar Feb 18 '25 19:02 IamJoshing

I have no idea. I tried it after everything else had failed. I found some other examples of metro configs on the Expo Discord with more condition names. I added in the condition names that I didn't have. It worked. Then I removed them individually until I knew it was 'browser'. If this works for others, maybe someone at Expo can give you an answer as to why.

Yes, that's correct. Just wanted to confirm this works and send a snippet to fix it here.

// metro.config.js
const config = {
    resolver: {
        unstable_conditionNames: ['browser'],
        unstable_enablePackageExports: false,
    }
};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);

HenriqueDerosa avatar Apr 14 '25 13:04 HenriqueDerosa

Just stumbled upon this as was facing this issue (using SDK 53 beta). This behavior is expected: Metro’s support for Node‑style conditional exports now strictly honors the configured “conditions” (require, import, etc.) when resolving a package’s exports field, and it will only consider the "browser" entry if you explicitly include "browser" in its condition list.

This change comes from Metro bundler and mentioned as a breaking change https://expo.dev/changelog/sdk-53-beta. Also mentions setting unstable_enablePackageExports: false.

rileysay avatar Apr 21 '25 14:04 rileysay

I have no idea. I tried it after everything else had failed. I found some other examples of metro configs on the Expo Discord with more condition names. I added in the condition names that I didn't have. It worked. Then I removed them individually until I knew it was 'browser'. If this works for others, maybe someone at Expo can give you an answer as to why.

Yes, that's correct. Just wanted to confirm this works and send a snippet to fix it here.

// metro.config.js const config = { resolver: { unstable_conditionNames: ['browser'], unstable_enablePackageExports: false, } };

module.exports = mergeConfig(getDefaultConfig(__dirname), config);

you saved me, thanks a lot!!

Utkarsh4517 avatar Apr 22 '25 20:04 Utkarsh4517

I just came here for Expo SDK 53 + Supabase combo and want to confirm this works:

Yes, that's correct. Just wanted to confirm this works and send a snippet to fix it here.

// metro.config.js const config = { resolver: { unstable_conditionNames: ['browser'], unstable_enablePackageExports: false, } };

module.exports = mergeConfig(getDefaultConfig(__dirname), config);

Although I rewrote it as:

// Expo SDK 53 + Supabase
config.resolver.unstable_conditionNames = ['browser']
config.resolver.unstable_enablePackageExports = false

tomsoderlund avatar May 03 '25 06:05 tomsoderlund

is there any solution about this bug???

afidhu avatar May 03 '25 19:05 afidhu

I can't disable package exports since I use this feature in my mono-repo project, instead, I added this config:

// metro.config.js
const config = {
  resolver: {
    resolveRequest: (context, moduleName, platform) => {
      if (moduleName === "ws") {
        return { type: "empty" };
      }
      return context.resolveRequest(context, moduleName, platform);
    },
  },
}

YowaiCoder avatar May 05 '25 14:05 YowaiCoder

we're releasing a next version of supabase-js to try and test out if a fix works: https://github.com/supabase/supabase-js/pull/1395

filipecabaco avatar May 09 '25 10:05 filipecabaco

The issue seems to be fixed in the latest version as reported by users, so I am closing this issue. If issue persists, please feel free to tag me here, or create a new issue. Thank you everyone!

mandarini avatar Oct 23 '25 10:10 mandarini