realm / realm-js

Realm is a mobile database: an alternative to SQLite & key-value stores
https://realm.io
Apache License 2.0
5.74k stars 565 forks source link

[React-Native]: Unable to resolve module "submit-analytics" at runtime #4459

Closed IronTony closed 2 years ago

IronTony commented 2 years ago

How frequently does the bug occur?

All the time

Description

After iOS and Android compilation, when the server starts to load the application, I receive this error:

I am using a custom RN boilerplate. If I add the realm package (10.20.0-beta.3) to the downloaded boilerplate and try to compile, the compilation will work and I do not receive the error above.

Instead when I use the same package in the same boilerplate but with also other packages installed (reanimated 2.5.0, apollo client 3.5.10, and so on...) I receive the error during the application load in the server (as the error above)

This is my metro.config.js

const { getDefaultConfig } = require('metro-config');
const { resolver: defaultResolver } = getDefaultConfig.getDefaultValues();

module.exports = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
  resolver: {
    ...defaultResolver,
    sourceExts: [...defaultResolver.sourceExts, 'cjs'],
  },
};

These are some packages in my package.json:

 "dependencies": {
    "@apollo/client": "3.5.10",
    "@react-native-async-storage/async-storage": "1.17.1",
    "@react-native-community/masked-view": "0.1.11",
    "@react-native-firebase/app": "14.7.0",
    "@react-native-firebase/messaging": "14.7.0",
    "@react-navigation/bottom-tabs": "6.2.0",
    "@react-navigation/devtools": "6.0.5",
    "@react-navigation/native": "6.0.8",
    "@react-navigation/stack": "6.1.1",
    "@tlon/sigil-js": "1.4.5",
    "apollo3-cache-persist": "0.14.0",
    "axios": "0.26.1",
    "bn.js": "^5.2.0",
    "date-fns": "2.28.0",
    "graphql": "16.3.0",
    "i18next": "21.6.14",
    "lodash": "^4.17.21",
    "pod-install": "^0.1.32",
    "react": "17.0.2",
    "react-i18next": "11.16.2",
    "react-native": "0.67.4",
    "react-native-animatable": "^1.3.3",
    "react-native-fast-image": "^8.5.11",
    "react-native-flipper": "0.140.0",
    "react-native-gesture-handler": "2.3.2",
    "react-native-indicators": "^0.17.0",
    "react-native-localize": "2.2.1",
    "react-native-mmkv": "^2.2.0",
    "react-native-reanimated": "2.5.0",
    "react-native-safe-area-context": "4.2.4",
    "react-native-screens": "3.13.1",
    "react-native-sensitive-info": "^5.5.8",
    "react-native-splash-screen": "3.3.0",
    "react-native-svg": "^12.1.1",
    "react-native-use-persist-storage": "^1.0.2",
    "react-native-vector-icons": "9.1.0",
    "react-native-version-number": "^0.3.6",
    "realm": "^10.20.0-beta.3",
    "typescript": "4.6.3",
  },
  "devDependencies": {
    "@babel/core": "7.17.8",
    "@babel/plugin-transform-arrow-functions": "^7.16.7",
    "@babel/plugin-transform-shorthand-properties": "^7.16.7",
    "@babel/runtime": "7.17.8",
    "@react-native-community/eslint-config": "3.0.1",
    "@react-native-community/eslint-plugin": "^1.1.0",
    "@trivago/prettier-plugin-sort-imports": "^3.2.0",
    "@types/jest": "27.4.1",
    "@types/node": "17.0.23",
    "@types/react": "17.0.43",
    "@types/react-native": "0.67.3",
    "@types/react-test-renderer": "^17.0.1",
    "@typescript-eslint/eslint-plugin": "5.17.0",
    "@typescript-eslint/parser": "5.17.0",
    "babel-jest": "27.5.1",
    "babel-plugin-module-resolver": "^4.1.0",
    "eslint": "7.32.0",
    "eslint-config-prettier": "8.5.0",
    "eslint-plugin-prettier": "4.0.0",
    "fast-glob": "3.2.11",
    "husky": "7.0.4",
    "jest": "27.5.1",
    "lint-staged": "12.3.7",
    "madge": "5.0.1",
    "metro-react-native-babel-preset": "0.69.1",
    "npm-run-all": "^4.1.5",
    "prettier": "2.6.1",
    "pretty-quick": "3.1.3",
    "react-native-debugger-open": "^0.3.25",
    "react-native-flipper-apollo-devtools": "^0.0.2",
    "react-native-flipper-databases": "2.3.1",
    "react-test-renderer": "17.0.2",
    "shx": "0.3.4",
    "ts-jest": "27.1.4"
  },

Stacktrace & log output

No response

Can you reproduce the bug?

Yes, always

Reproduction Steps

No response

Version

10.20.0-beta.3

What SDK flavour are you using?

Local Database only

Are you using encryption?

No, not using encryption

Platform OS and version(s)

iOS and Android

Build environment

No response

Cocoapods version

No response

kraenhansen commented 2 years ago

Thanks for creating an issue.

In the hermes branch, we rely on the bundler (or whatever resolves package main fields) look for the "react-native" main field. We think this is reasonable, since it is default behaviour of the Metro server when invoked via the React Native CLI.

It seems to me that the babel-plugin-module-resolver package resolves main fields like Node.js (primarily looking for a "main" field) as it uses the resolve package to perform the resolution. Neither seem to export an easy way to configure the main field, so I'd expect these to be packages primarily written for the Node.js community. The resolve package does have an option (packageFilter) to transform the package.json before it's resolved, but that isn't used or exposed through the babel plugin. Perhaps one could implement a variant of the resolvePath function which would work reliably in a React Native project.

The ideal solution to me, would be that the module-resolver Babel plugin exposed a way to configure "main fields" to look for. As a potential solution for this specific issue, I see that we might be able to drop a lib/index.native.js which simply re-exports our lib/react-native/index.js effectively implementing the "native-specific extension": https://reactnative.dev/docs/platform-specific-code#native-specific-extensions-ie-sharing-code-with-nodejs-and-web.

I'll get a release out with this fix and 🀞 that's enough.

IronTony commented 2 years ago

Hi @kraenhansen, thank you so much for the detailed explanation, really appreciated. I will wait for the fix release and I hope that it will be enough.

Moreover I did some other tests, and I found a strange thing.

Here is an extract of my App.tsx

<Suspense fallback={<SCLSplashscreen />}>
      <ApolloProvider client={client}>
        <RealmProvider>
          <View>
            <Text>TEST</Text>
          </View>
        </RealmProvider>
     </ApolloProvider>
</Suspence>

And this is my Realm provider:

import Loader from '@components/Loader';
import React, { createRef, useEffect, useState } from 'react';
import Realm from 'realm';
import { realmDBContext } from './context';
import User from './models/user';

// Open a local realm file with the schema(s) that are a part of this realm.
const config = {
  schema: [User.schema],
};

const realmRef = createRef<Realm>();

const openRealm = async () => {
  const realm = await Realm.open(config); // <<<< BROKE THE COMPILATION AT RUNTIME!!!!
  realmRef.current = realm;

  /// FlipperDatabasesPlugin - START
  if (__DEV__) {
    // Import connectDatabases function and required DBDrivers
    const { connectDatabases, RealmDB } = require('react-native-flipper-databases');
    connectDatabases([
      new RealmDB('Realm', realm), // Pass in realm reference
    ]);
  }
  /// FlipperDatabasesPlugin - END
};

export const RealmProvider: React.FC = ({ children }) => {
  const [isReady, setReady] = useState(false);

  useEffect(() => {
    openRealm().then(() => {
      setReady(!realmRef?.current?.isClosed);
    });

    // Return a cleanup callback to close the realm to prevent memory leaks
    return () => {
      const realm = realmRef.current;
      realm?.close();
      realmRef.current = null;
      setReady(!realm?.isClosed);
    };
  }, []);

  if (!isReady || !realmRef.current) {
    return <Loader fullPage />;
  }

  return <realmDBContext.Provider value={realmRef}>{children}</realmDBContext.Provider>;
};
IronTony commented 2 years ago

Hi @kraenhansen I tried to install the hermes branch (yarn add realm@hermes), but it seems to that the version is not the last one with your commits, in fact I have always the same error during runtime

kraenhansen commented 2 years ago

@IronTony I'm awaiting an "upstream" release on the master channel before I can get this out. I hope to get it released in the start of the coming week. Sorry for the delay here.

IronTony commented 2 years ago

@kraenhansen no problem. I thought I was doing something wrong. Thank you

kraenhansen commented 2 years ago

@IronTony we have a new release out with a fix for this 🀞 Please try out v10.20.0-beta.4 and reopen if the issue persists.

IronTony commented 2 years ago

Thank you. I will try tomorrow and for the best!!! 🀞🏼🀞🏼🀞🏼