expo: [iOS 16.4 + JSC]: Unable to resolve [package] from [dependency/file/path]

Summary

When trying to build, I get a number of issues about being unable to resolve files from dependencies of my project. For example:

Unable to resolve "@ledgerhq/devices/hid-framing" from "node_modules/@ledgerhq/hw-transport-webhid/lib/TransportWebHID.js"

"@ledgerhq/devices/hid-framing" from "node_modules/@ledgerhq/hw-transport-webusb/lib/TransportWebUSB.js"

Unable to resolve "@react-native-async-storage/async-storage" from "node_modules/@walletconnect/keyvaluestorage/dist/cjs/react-native/index.js"

Replacing these imports with undefined for testing causes errors like the following until node_modules is cleaned and dependencies are reinstalled

None of these files exist:
  * node_modules/react-native/Libraries/Components/DatePicker/DatePickerIOS(.native|.native.ts|.ts|.native.tsx|.tsx|.native.js|.js|.native.jsx|.jsx|.native.json|.json)
  * node_modules/react-native/Libraries/Components/DatePicker/DatePickerIOS/index(.native|.native.ts|.ts|.native.tsx|.tsx|.native.js|.js|.native.jsx|.jsx|.native.json|.json)
  15 | import typeof ActivityIndicator from './Libraries/Components/ActivityIndicator/ActivityIndicator';
  16 | import typeof Button from './Libraries/Components/Button';
> 17 | import typeof DatePickerIOS from './Libraries/Components/DatePicker/DatePickerIOS';
     |                                   ^
  18 | import typeof DrawerLayoutAndroid from './Libraries/Components/DrawerAndroid/DrawerLayoutAndroid';
  19 | import typeof FlatList from './Libraries/Lists/FlatList';
  20 | import typeof Image from './Libraries/Image/Image';

What platform(s) does this occur on?

No response

SDK Version

47.0.12

Environment

expo-env-info 1.0.5 environment info:
    System:
      OS: macOS 13.3
      Shell: 5.9 - /bin/zsh
    Binaries:
      Node: 18.12.1 - ~/.nvm/versions/node/v18.12.1/bin/node
      Yarn: 1.22.19 - ~/.nvm/versions/node/v18.12.1/bin/yarn
      npm: 8.19.2 - ~/.nvm/versions/node/v18.12.1/bin/npm
      Watchman: 2023.03.13.00 - /opt/homebrew/bin/watchman
    Managers:
      CocoaPods: 1.12.0 - /opt/homebrew/bin/pod
    SDKs:
      iOS SDK:
        Platforms: DriverKit 22.4, iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4
    IDEs:
      Android Studio: 2021.2 AI-212.5712.43.2112.8815526
      Xcode: 14.3/14E222b - /usr/bin/xcodebuild
    npmPackages:
      expo: ~47.0.12 => 47.0.13 
      react: 18.1.0 => 18.1.0 
      react-native: 0.70.5 => 0.70.5 
    Expo Workflow: managed

Minimal reproducible example

Repo can be found here: https://github.com/billyjacoby/expo-unable-to-resolve

There’s a branch using the most up to date Expo-CLI there as well

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 7
  • Comments: 18 (5 by maintainers)

Commits related to this issue

Most upvoted comments

I’m also using Hermes and running into the same issues but only with Expo and not in a bare React native project @mypalvikram @brentvatne

In the repo I originally linked I included a branch that is using the 48 version of Expo (hermes support) and get all the same errors: https://github.com/billyjacoby/expo-unable-to-resolve/blob/updated-expo-cli/package.json

thanks @IlyaSemenov! the workaround suggested by @robhogan in https://github.com/facebook/react-native/issues/36794#issuecomment-1500880284 will work, with a slight tweak to extend the default expo metro config:

const { getDefaultConfig } = require('expo/metro-config');

const config = getDefaultConfig(__dirname);
config.server.rewriteRequestUrl = (url) => {
  if (!url.endsWith('.bundle')) {
    return url;
  }
  // https://github.com/facebook/react-native/issues/36794
  // JavaScriptCore strips query strings, so try to re-add them with a best guess.
  return url + '?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true';
};

module.exports = config;

alternatively, switching to hermes will resolve this and is a good choice! it is the default in sdk 48 and we recommend it.

This is probably caused by the recent problem in iOS 16.4: https://github.com/facebook/react-native/issues/36794

@brentvatne You may want to consider to reopen the issue as it’s a valid problem confirmed by RN upstream. Expo may want to have its own suggested workaround.

any fix? it’s been 4 months…

@mypalvikram - the react-native team is working on a fix: https://github.com/facebook/react-native/issues/36794#issuecomment-1519544863

however, i personally would recommend that you use this as one more piece of motivation to switch from jsc to hermes. that will also resolve the issue and bring many other benefits, such as an improved debugging experience

I’m actually using Expo version 48 and Hermes is default but, I still run into this. This makes me think that there’s potentially another package causing this issue in my case. Thanks for the feedback, I’ll dig a little more.

I added that code in my expo metro config but I still get the same error. Fair enough, the app takes longer before crashing, but it still does.

Here is my metro.config.js file. Is there anything I’m doing wrong?

const { getDefaultConfig } = require("metro-config")
const { getDefaultConfig: getDefaultExpoConfig } = require("@expo/metro-config")

let metroConfig
let isExpo = false
try {
  const Constants = require("expo-constants")
  // True if the app is running in an `expo build` app or if it's running in Expo Go.
  
  isExpo =
    Constants.executionEnvironment === "standalone" ||
    Constants.executionEnvironment === "storeClient"
} catch { }

if (isExpo) {

  metroConfig = getDefaultExpoConfig(__dirname)

  metroConfig.resolver.assetExts.push('cjs');

  // START: This is a workaround for an upstream bug in react-native

  metroConfig.server.rewriteRequestUrl = (url) => {
    if (!url.endsWith('.bundle')) {
      return url;
    }
    // https://github.com/facebook/react-native/issues/36794
    // JavaScriptCore strips query strings, so try to re-add them with a best guess.
    return url + '?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true';
  };
  
  // END
  
} else {
  
  const { makeMetroConfig } = require("@rnx-kit/metro-config")
  const MetroSymlinksResolver = require("@rnx-kit/metro-resolver-symlinks")

  metroConfig = (async () => {
    const defaultConfig = await getDefaultConfig()
    return makeMetroConfig({
      projectRoot: __dirname,
      
      // watchFolders: [`${__dirname}/../..`], // for monorepos
      resolver: {
      
        resolveRequest: MetroSymlinksResolver(),

        assetExts: [...defaultConfig.resolver.assetExts, "bin", "cjs"],
      },
      })
  })()

}

module.exports = metroConfig