react-native-community / cli

The React Native Community CLI - command line tools to help you build RN apps
MIT License
2.4k stars 904 forks source link

CLI fails when dev dependencies are not installed #1750

Closed elliotdickison closed 1 year ago

elliotdickison commented 2 years ago

Environment

System:
    OS: macOS 12.6.1
    CPU: (8) arm64 Apple M1
    Memory: 588.30 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.15.0 - ~/.volta/tools/image/node/16.15.0/bin/node
    Yarn: 1.22.17 - ~/.volta/tools/image/yarn/1.22.17/bin/yarn
    npm: 8.5.5 - ~/.volta/tools/image/node/16.15.0/bin/npm
    Watchman: Not Found
  Managers:
    CocoaPods: 1.11.3 - /opt/homebrew/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 22.1, iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1
    Android SDK:
      API Levels: 31, 33
      Build Tools: 28.0.3, 29.0.2, 30.0.2, 30.0.3, 31.0.0
      System Images: android-31 | ARM 64 v8a, android-S | Google APIs ARM 64 v8a, android-S | Google Play ARM 64 v8a
      Android NDK: Not Found
  IDEs:
    Android Studio: 2021.1 AI-211.7628.21.2111.8193401
    Xcode: 14.1/14B47b - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.11 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 18.1.0 => 18.1.0
    react-native: 0.70.5 => 0.70.5
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Description

The CLI fails with the error Failed to load configuration of your project. if any development dependencies listed in package.json are not installed (even if those dependencies are not actually referenced anywhere in the project).

Potentially related issues: #1169 #1681

Reproducible Demo

  1. npx create-expo-app test-rn-app
  2. cd ./test-rn-app
  3. npm install left-pad --save-dev
  4. npm install --production
  5. npx react-native info (fails)
elliotdickison commented 2 years ago

Here's my temporary workaround (wrapping the config logic that searches through dependencies in a try/catch):

diff --git a/build/loadConfig.js b/build/loadConfig.js
index fcf5068470e8ec71c2fbd8c8e5eb701679107acb..798972f2b8088ab588cea7ba4bcb61a8055b2c4c 100644
--- a/build/loadConfig.js
+++ b/build/loadConfig.js
@@ -90,22 +90,29 @@ function loadConfig(projectRoot = (0, _cliTools().findProjectRoot)()) {
   };
   const finalConfig = Array.from(new Set([...Object.keys(userConfig.dependencies), ...(0, _findDependencies.default)(projectRoot)])).reduce((acc, dependencyName) => {
     const localDependencyRoot = userConfig.dependencies[dependencyName] && userConfig.dependencies[dependencyName].root;
-    let root = localDependencyRoot || (0, _cliTools().resolveNodeModuleDir)(projectRoot, dependencyName);
-    let config = (0, _readConfigFromDisk.readDependencyConfigFromDisk)(root, dependencyName);
-    const isPlatform = Object.keys(config.platforms).length > 0;
-    return (0, _assign.default)({}, acc, {
-      dependencies: (0, _assign.default)({}, acc.dependencies, {
-        get [dependencyName]() {
-          return getDependencyConfig(root, dependencyName, finalConfig, config, userConfig, isPlatform);
-        }
-
-      }),
-      commands: [...acc.commands, ...config.commands],
-      platforms: { ...acc.platforms,
-        ...config.platforms
-      },
-      healthChecks: [...acc.healthChecks, ...config.healthChecks]
-    });
+    // PATCH: Wrap this logic in a try/catch so that the CLI doesn't fail in
+    // production mode when dev dependencies aren't installed. See:
+    // https://github.com/react-native-community/cli/issues/1750
+    try {
+      let root = localDependencyRoot || (0, _cliTools().resolveNodeModuleDir)(projectRoot, dependencyName);
+      let config = (0, _readConfigFromDisk.readDependencyConfigFromDisk)(root, dependencyName);
+      const isPlatform = Object.keys(config.platforms).length > 0;
+      return (0, _assign.default)({}, acc, {
+        dependencies: (0, _assign.default)({}, acc.dependencies, {
+          get [dependencyName]() {
+            return getDependencyConfig(root, dependencyName, finalConfig, config, userConfig, isPlatform);
+          }
+
+        }),
+        commands: [...acc.commands, ...config.commands],
+        platforms: { ...acc.platforms,
+          ...config.platforms
+        },
+        healthChecks: [...acc.healthChecks, ...config.healthChecks]
+      });
+    } catch (_error) {
+      return acc
+    }
   }, initialConfig);
   return finalConfig;
 }
TMisiukiewicz commented 1 year ago

Hi @elliotdickison, thanks for reporting a bug. Gonna take a look on this one