nx icon indicating copy to clipboard operation
nx copied to clipboard

JS Libraries not working with expo

Open sem4phor opened this issue 1 year ago • 3 comments

Current Behavior

Javascript libraries generated by npx nx g @nx/js:lib mylib cannot be resolved in apps generated with nx generate @nrwl/expo:application my-app.

Unable to resolve "@expo-workspace/mylib" from "src/app/App.tsx"

I want to share js libs between frontend & backend so creating an expo lib would not fit the use-case.

Expected Behavior

Functions exported by js libraries can be consumed in an expo project.

GitHub Repo

https://github.com/sem4phor/expo-jslib-bug

Steps to Reproduce

First 3 Steps can be skipped by using the reproduction repo.

  1. Follow https://nx.dev/packages/expo to create a new expo project (you might need to update the react-native version)
  2. generate a js library by following https://nx.dev/packages/js/generators/library (tsc build)
  3. import the function from the generated lib in App.tsx
  4. Run nx start my-app
  5. Press 'w' to open expo web
  6. See error in console

Nx Report

>  NX   Report complete - copy this into the issue template

   Node   : 16.13.1
   OS     : darwin arm64
   npm    : 8.3.0
   Hasher : Native
   
   nx                 : 16.3.2
   @nx/js             : 16.3.2
   @nx/jest           : 16.3.2
   @nx/linter         : 16.3.2
   @nx/workspace      : 16.3.2
   @nx/detox          : 16.3.2
   @nx/devkit         : 16.3.2
   @nx/eslint-plugin  : 16.3.2
   @nx/expo           : 16.3.2
   @nx/react          : 16.3.2
   @nrwl/tao          : 16.3.2
   @nx/web            : 16.3.2
   @nx/webpack        : 16.3.2
   typescript         : 5.0.4
   ---------------------------------------
   Local workspace plugins:
         @expo-workspace/mylib

Failure Logs

Web Bundling complete 116ms
› Open in the web browser...
› Press ? │ show all commands
Web Bundling failed 68ms
Unable to resolve "@expo-workspace/mylib" from "src/app/App.tsx"
› Stopped server

Operating System

  • [X] macOS
  • [ ] Linux
  • [ ] Windows
  • [ ] Other (Please specify)

Additional Information

Error goes away when removing package.json from my-lib (but then other code breaks. e.g. other js libs consuming these) OR adding main field to package json ("main": "src/index.ts")

sem4phor avatar Jun 06 '23 14:06 sem4phor

i pushed up a pr to your repo: https://github.com/sem4phor/expo-jslib-bug/pull/1/files#diff-648b685b88a9c0026ac179c0753d8a4813a6a0f4deb4a4a34d714b46bfce1bb1 the issue is that you got a buildable expo library with package.json. when metro tries to resolve the library, instead of reading from tsconfig path, it tries to read from package.json. there is no main specified in package.json, it will go to index files in the package root. by adding a index under package will solve it.

or you can also add main the the package.json:

"main": "src/index.ts"

however, i still need to push up a proper fix for buildable expo libraries.

xiongemi avatar Jun 08 '23 19:06 xiongemi

Diving a bit in the expo plugin code (node_modules/@nx/expo/plugins/with-nx-metro.js line 16-17) I found following lines:

// Add support for paths specified by tsconfig
    config.resolver = Object.assign(Object.assign({}, config.resolver), { resolveRequest: (0, metro_resolver_1.getResolveRequest)(extensions) });

which suggests that paths from tsconfig should resolve correctly. and as tsconfig base is extended i would expect that the paths resolve to the correct index files without the need of the extra index file 🤔

sem4phor avatar Jun 12 '23 09:06 sem4phor

i turned on the debug verbose option, however, I realized this import did not even hit the metro resolver and did not hit the line below. I think the quickest workaround is just to add the index under the js lib root and re-export everything for this library. i think it might be related to metro? not sure whether upgrading metro would resolve this. let's see react native 0.72 would solve this.

Diving a bit in the expo plugin code (node_modules/@nx/expo/plugins/with-nx-metro.js line 16-17) I found following lines:

// Add support for paths specified by tsconfig
    config.resolver = Object.assign(Object.assign({}, config.resolver), { resolveRequest: (0, metro_resolver_1.getResolveRequest)(extensions) });

which suggests that paths from tsconfig should resolve correctly. and as tsconfig base is extended i would expect that the paths resolve to the correct index files without the need of the extra index file 🤔

xiongemi avatar Jun 16 '23 16:06 xiongemi

Thanks, was running into this issue. Adding the main value in package.json helped me get past the issue

If anyone is having a similar issue with NX 16 and @nx/expo 16:

What solved it for me was to make sure that when creating the library in nx, explicitly specify the nested directory "libs" using the option --directory=libs/<lib-name>:

npx nx g @nx/expo:lib ui --directory=libs/ui --buildable

The option --buildable may also be necessary, otherwise no build action is added (and no package.json is added).

diatche avatar Sep 19 '23 00:09 diatche

As far as I can tell, the documentation either says nothing about 'libs' or it says it's just an option: https://nx.dev/concepts/more-concepts/applications-and-libraries - (A typical Nx workspace is structured into "apps" and "libs".) Nothing tells me it's required. As far as I can tell however, nx/expo seems to require it. Here is a script to reproduce a clean workspace with and without the libs folder. The one with works and the one without can't resolve. I have seen many issues raised related to metro being unable to resolve packages and I wonder if they could related to this or other idiosyncrasies like it. In any case, here is the script to reproduce from a clean workspace.

npx create-nx-workspace@latest broken-demo --preset=expo --nxCloud=false --appName=broken cd broken-demo npx nx g @nx/js:library broken-lib --unitTestRunner=none --bundler=tsc awk 'NR==14{print "import { brokenLib } from '''@broken-demo/broken-lib''';"}1' ./apps/broken/src/app/App.tsx > temp.txt && mv temp.txt ./apps/broken/src/app/App.tsx awk 'NR==34 {gsub("Broken", "{brokenLib()}"); print; next} 1' ./apps/broken/src/app/App.tsx > temp.txt && mv temp.txt ./apps/broken/src/app/App.tsx awk 'NR==8 {gsub("./src/index.js", "./src/index.ts"); print; next} 1' ./broken-lib/package.json > temp.txt && mv temp.txt ./broken-lib/package.json npx nx run broken:start cd ..

npx create-nx-workspace@latest working-demo --preset=expo --nxCloud=false --appName=working cd working-demo npx nx g @nx/js:library working-lib --unitTestRunner=none --bundler=tsc --directory=libs --projectNameAndRootFormat=derived awk 'NR==14{print "import { workingLib } from '''@working-demo/working-lib''';"}1' ./apps/working/src/app/App.tsx > temp.txt && mv temp.txt ./apps/working/src/app/App.tsx awk 'NR==34 {gsub("Working", "{workingLib()}"); print; next} 1' ./apps/working/src/app/App.tsx > temp.txt && mv temp.txt ./apps/working/src/app/App.tsx awk 'NR==8 {gsub("./src/index.js", "./src/index.ts"); print; next} 1' ./libs/working-lib/package.json > temp.txt && mv temp.txt ./libs/working-lib/package.json npx nx run working:start cd ..

jessephelps avatar Oct 04 '23 20:10 jessephelps

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs. If we missed this issue please reply to keep it active. Thanks for being a part of the Nx community! 🙏

github-actions[bot] avatar Apr 02 '24 00:04 github-actions[bot]

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.

github-actions[bot] avatar May 17 '24 00:05 github-actions[bot]