react-native: RN 0.56 & 0.57 - providesModule no longer works

Environment

React Native Environment Info: System: OS: macOS Sierra 10.12.6 CPU: x64 Intel® Core™ i7-7700HQ CPU @ 2.80GHz Memory: 365.54 MB / 16.00 GB Shell: 5.2 - /bin/zsh Binaries: Node: 9.4.0 - /usr/local/bin/node Yarn: 1.3.2 - /usr/local/bin/yarn npm: 5.6.0 - /usr/local/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman SDKs: iOS SDK: Platforms: iOS 11.1, macOS 10.13, tvOS 11.1, watchOS 4.1 Android SDK: Build Tools: 26.0.2, 27.0.1, 27.0.3 API Levels: 25, 26, 27 IDEs: Android Studio: 3.1 AI-173.4907809 Xcode: 9.1/9B55 - /usr/bin/xcodebuild npmPackages: react: 16.5.0 => 16.5.0 react-native: 0.57.0 => 0.57.0 npmGlobalPackages: create-react-native-app: 1.0.0 react-native-git-upgrade: 0.2.7

Description

ProvidesModule does not seem to work after RN version 0.55.4. Tested on both 0.56.1 and 0.57.0 with the same result.

When creating a brand new React Native project using react-native init and utilising providesModule, the metro bundler complains with the following error -

error: bundling failed: Error: Unable to resolve module `App` from `../TestApp/index.js`: Module `App` does not exist in the Haste module map

This might be related to https://github.com/facebook/react-native/issues/4968
To resolve try the following:
  1. Clear watchman watches: `watchman watch-del-all`.
  2. Delete the `node_modules` folder: `rm -rf node_modules && npm install`.
  3. Reset Metro Bundler cache: `rm -rf /tmp/metro-bundler-cache-*` or `npm start -- --reset-cache`.
  4. Remove haste cache: `rm -rf /tmp/haste-map-react-native-packager-*`.
    at ModuleResolver.resolveDependency (../TestApp/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:209:1301)
    at ResolutionRequest.resolveDependency (../TestApp/node_modules/metro/src/node-haste/DependencyGraph/ResolutionRequest.js:83:16)
    at DependencyGraph.resolveDependency (../TestApp/node_modules/metro/src/node-haste/DependencyGraph.js:238:485)
    at Object.resolve (../TestApp/node_modules/metro/src/lib/transformHelpers.js:180:25)
    at dependencies.map.result (../TestApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:311:29)
    at Array.map (<anonymous>)
    at resolveDependencies (../TestApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:307:16)
    at ../TestApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:164:33
    at Generator.next (<anonymous>)
    at step (../TestApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:266:307)

This is the case when using providesModules in any file and importing it. This is a regression on the following versions of RN 0.56.0, 0.56.1 and 0.57.0; but works as expected in 0.55.4.

Reproducible Demo

Please see the sample project I have created here - https://github.com/thomas-gilbert/react-native-57-issue. The only change I have made from the standard output of react-native init, can be seen in this commit https://github.com/thomas-gilbert/react-native-57-issue/commit/15bd63bfd09b9f48993ce5a37273f3be9647235b.

Steps to reproduce -

  1. Run react-native init TestApp.
  2. Modify App.js by adding the providesModule annotation at the top of the file e.g @providesModule App.
  3. Modify index.js with import App from 'App'.
  4. react-native run-android.
  5. Error should be seen.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 3
  • Comments: 21 (6 by maintainers)

Most upvoted comments

Yay! I knew you could do it!

Thanks a lot. Your comments made thing much clearer. I will try this approach later this week.

I am removing @provideModule, but imports are failing if it is imported by file name (without path). As I have over 250 @provideModuledeclarations and every single file has import what would be needed to add path I am looking for less painful solution. Now added babel-plugin-module-resolver plugin and mapping modules in .babelrc file. It does work, but for me it does not feel like a proper way to handle it. If RN is designed to have out of the box solution I would love to use it. But so far can’t find any proper description. Have a feeling that you might be the one who could point me and others 😃

hasteImpl is the configuration file where you can specify how file names map to the haste name. Here is an example: https://github.com/facebook/react-native/blob/master/jest/hasteImpl.js#L58-L78