elbywan / wretch

A tiny wrapper built around fetch with an intuitive syntax. :candy:
MIT License
4.83k stars 98 forks source link

Unable to resolve any addon in Expo React Native project #218

Closed thisisomar closed 8 months ago

thisisomar commented 9 months ago

Hey there!

I am having a weird issue when using the FormDataAddon or even any addon for that matter with Wretch in a React Native Expo (with TypeScript) project.

I get this error on attempting to import an addon (this happens when running the project)

Unable to resolve "wretch/addons/formData" from "api/api.ts"

I've created a reproducible example here. This is the Expo RN TypeScript template - I am using Node 18.16.0.

I tried spending a bit of time to look into the issue, and I discovered that specifying the full relative path works completely fine:

import FormDataAddon from "../node_modules/wretch/dist/addons/formData"

So I presume this may be an issue with Expo's bundling?

elbywan commented 9 months ago

Hey @thisisomar, thanks for reporting the issue 👍

So I presume this may be an issue with Expo's bundling?

Yes, more specifically with the metro bundler which does not support package exports by default.

It seems to work fine on my end when customizing the config file:

# will generate a metro config file:
npx expo customize metro.config.js
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);
config.resolver.unstable_enablePackageExports = true; // <- ADD THIS

module.exports = config;
thisisomar commented 9 months ago

Hey thanks for the speedy response, appreciate it! I see, yeah this is what I was thinking

I tried enabling this in the repro I provided and it works, but doing this in my main project with other packages installed (react query, react hook forms to name a couple as they're the ones complaining), my project fails to run so I am not sure if this is a viable solution.

Is there an alternative here?

elbywan commented 9 months ago

Is there an alternative here?

You could try using a custom resolver in the metro config:

config.resolver.resolveRequest = (context, moduleName, platform) => {
  if (moduleName.startsWith('wretch/addons')) {
    return {
      filePath: require.resolve(moduleName),
      type: 'sourceFile',
    };
  }
  return context.resolveRequest(context, moduleName, platform);
}
thisisomar commented 8 months ago

Ahh yeah this works, thanks - good time to get myself familiar with Metro bundling. I think we can close this issue out, hopefully someone else will find this helpful - I will let you close it if you think everything is good on your end