"Unable to resolve module path" of large JS file

Dear all,

I’m running into this error message when trying to run my project in iOS/Android simulator (expo start - ‘i’ or ‘a’). When I open my project for Web (‘w’), that works fine.

Failed building JavaScript bundle.
Unable to resolve module path from /path/to/mymodule.js: path could not be found within the project.

If you are sure the module exists, try these steps:
 1. Clear watchman watches: watchman watch-del-all
 2. Delete node_modules and run yarn install
 3. Reset Metro's cache: yarn start --reset-cache
 4. Remove the cache: rm -rf /tmp/metro-*
  170 | // `/` should be present at the end if `scriptDirectory` is not empty
  171 | var scriptDirectory = '';
> 172 | function locateFile(path) {
      |                     ^
  173 |   if (Module['locateFile']) {
  174 |     return Module['locateFile'](path, scriptDirectory);
  175 |   }

I’m very sure that “/path/to/mymodule.js” exists and I have already tried all hints mentioned. There is no difference when building with yarn or npm either.

A little bit of background:

  • The project itself is very simple; the only change w.r.t. the default project (expo init) is that it imports a .js module: mymodule.js. Unfortunately, I’m not able to share this file with you.
  • mymodule.js is a very large JavaScript file (10MB)
  • It was built using Emscripten (with WASM=0 and -O0 flags, so a single .js file is output)
  • I needed to increase the JavaScript heap memory (export NODE_OPTIONS="--max-old-space-size=8192") for it to be able to build (for Expo Web, which works).
  • A simpler/smaller module -built in the same way using Emscripten- can successfully be imported/build/run in Expo on both Web, iOS and Android.

Questions:

  • Has anybody had a similar problem or error message?
  • Is there any reason why a large module would not run?
  • Does anybody have any idea why it would build and run for Web but not for iOS/Android? That might help me to solve the issue.

Any hint is appreciated. Thanks in advance!

Kind regards,
Sander

Expo CLI 4.3.2 environment info:
System:
OS: macOS 10.15.7
Shell: 5.0.16 - /usr/local/bin/bash
Binaries:
Node: 12.16.2 - /usr/local/bin/node
Yarn: 1.22.4 - /usr/local/bin/yarn
npm: 6.14.9 - /usr/local/bin/npm
Managers:
CocoaPods: 1.9.1 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: iOS 14.1, DriverKit 19.0, macOS 10.15, tvOS 14.0, watchOS 7.0
IDEs:
Android Studio: 4.0 AI-193.6911.18.40.6514223
Xcode: 12.1/12A7403 - /usr/bin/xcodebuild
npmPackages:
expo: ~40.0.0 => 40.0.1
react: 16.13.1 => 16.13.1
react-dom: 16.13.1 => 16.13.1
react-native: https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz => 0.63.2
react-native-web: ~0.13.12 => 0.13.18
npmGlobalPackages:
expo-cli: 4.3.2
Expo Workflow: managed

Building with compiler flag ENVIRONMENT=web solved this problem for me.

Glad you worked it out.
Could you explain how/where you specified this compiler flag?
According to your expo diagnostics output this is a managed project. Have you ejected since the first post?

I will tell a bit more about what I did. I had a program written in C, which I wanted to call from an Expo project.

Let’s take this simple C program:

#include <stdio.h>
#include <emscripten.h>

EMSCRIPTEN_KEEPALIVE
int pingIt() {
  return 1;
}

This can be compiled into JavaScript using Emscripten with this command line:

emcc ping.c -o ping.js -s WASM=0 -s ENVIRONMENT=web -s MODULARIZE=1 -s "EXPORT_NAME='createPingModule'"

…resulting in ping.js, which can be added to your Expo project and can then be called from Expo App.js like:

import createPingModule from './ping';

...

createPingModule()
  .then(module => {
    console.log('Module created!');
    let a = module._pingIt();
    console.log(a);
});

My actual C program is pretty complex, even including OpenCV (compiled for JavaScript; opencv.js) for some image processing, but it still works inside a managed Expo project.