satya164 / use-latest-callback

React hook which returns the latest callback without changing the reference.
https://npmjs.com/package/use-latest-callback
38 stars 7 forks source link

Issue with exports field in package.json #9

Open OzymandiasTheGreat opened 4 months ago

OzymandiasTheGreat commented 4 months ago

First I'd like to apologize because I haven't researched this as much as I could (it's weekend and I'm tired) So something about the way exports field is defined in this package breaks react-native. Since react-navigation depends on this package, it will soon be a big issue. I say soon, because right now exports field support in react-native is experimental and disabled by default. It should be enabled in coming weeks. Right now, enabling support for exports field in react-native results in empty default export for this package. The module is resolved, but calling the hook throws TypeError: _useLatestCallback is not a function

satya164 commented 4 months ago

From my testing this code works on Node.js, Vite & Webpack. It's based on the recommendation from Node.js docs: https://nodejs.org/api/packages.html#approach-1-use-an-es-module-wrapper

So if Metro is not working with it, then I think the behavior is incorrect. Since it's still experiemental, I think it'd be better to open a bug report in Metro.

andyjxli commented 4 months ago

https://github.com/satya164/use-latest-callback/pull/7 I have solved this problem in this PR, our company all RN project have use the metro config "unstable_enablePackageExports: true", so we need to solve this problem. We use "resolutions" field to solve at now

satya164 commented 4 months ago

@andyjxli according to metro docs, exports is used first https://metrobundler.dev/docs/package-exports#breaking-match-exports-first-then-fall-back-to-legacy-resolution

"exports" will be used instead of any existing "react-native", "browser", or "main" field

So I don't think adding react-native would override that.

jkhaui commented 3 months ago

I wanted to add another case where this is breaking:

Use latest callback is a transitive dependency in my Vite-based web app (using react-navigation/native and rnw).

In a minimal dev environment, everything works okay. But a production build with rollup leads to the "is not a function" error.

I'll try dig deeper and report findings.

edit: also, I'm not sure it's a metro problem because failing in production with Vite implies this package also breaks with rollup.

jkhaui commented 3 months ago

Findings:

  1. Using pnpm overrides to force use-latest-callback to 0.1.9 fixes the issue in a rollup prod build using react-navigation/native
  2. What I find super weird, though, is that now my development environment breaks with 0.1.9.

So right now I'm forced into this weird workaround with Vite such that 0.1.9 is used in prod and 0.2.1 in dev.