facebook / metro

🚇 The JavaScript bundler for React Native
https://metrobundler.dev
MIT License
5.24k stars 626 forks source link

Android 0.73.9 failing to compile on metro #1365

Closed mobinni closed 1 month ago

mobinni commented 1 month ago

Do you want to request a feature or report a bug? Bug

What is the current behavior?

When I upgraded from 0.72.11 to 0.73.9 I also upgraded my metro to be on version 0.80.12 On iOS everything works fine with the bundler, however when we run the Android app with the bundler it fails to find .cxx files.

We get the following error:

modules/metro/src/Server.js:1026:22)
    at async Server._processRequest ...monorepo/node_modules/metro/src/Server.js:419:7) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '/root/react-native/packages/react-native/ReactAndroid/hermes-engine/.cxx/Release/6f315kj6/arm64-v8a/lib/InternalBytecode/InternalBytecode.js'

When we downgrade back to metro 0.76.0 everything on Android works fine however, I'm wondering if for some reason it's assuming new architecture for Android? Not really sure how to debug this or create a reproducible mini example as it works fine for iOS.

Metro config:

const path = require('path');
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { FileStore } = require('metro-cache');

const defaultConfig = getDefaultConfig(__dirname);
const { assetExts } = defaultConfig.resolver;

// Learn more https://docs.expo.dev/guides/monorepos
// Find the project and workspace directories

const projectRoot = __dirname;

const workspaceRoot = path.join(__dirname, '../../../');

const config = {
  transformer: {
    babelTransformerPath: require.resolve('./customTransformer.js'),
  },
  resolver: {
    assetExts: assetExts,
    // in order of most-to-least used file extensions for performance during resolution
    sourceExts: ['ts', 'js', 'tsx', 'graphql', 'mjs', 'json'],
  },
  cacheStores: [
    new FileStore({
      root: path.join(__dirname, '.metro-cache'),
    }),
  ],

  // Watch all files within the monorepo
  watchFolders: [workspaceRoot],
  projectRoot,
};

module.exports = mergeConfig(defaultConfig, config);

customTransformer:

module.exports.transform = function (args) {
  const { src, filename, options } = args;
  const gqlTransform = gqlLoader.bind({
    cacheable: () => null,
  });

    // Do custom transformations
    let result = src;
    if (filename.endsWith('.gql') || filename.endsWith('.graphql')) {
      result = gqlTransform(result);
    }

    const babelCompileResult = upstreamTransformer.transform({
      src: result,
      filename,
      options,
    });

    // Pass the transformed source to the original react native transformer
    return babelCompileResult;
}

Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system. Node: 20.11 Yarn 1.22.22 Mac: Sonoma 14.7

Update 1 So the error above wasn't actually the root error, the root error was it could not find the files related to my monorepo structure stemming from a lazy import.

So I feel like I've tracked this down to be an issue specifically in Android on 0.73.9 where dynamic imports import(...) are breaking for lazy loaded screens in react-navigation.

When I change my imports to be top-level everything loads fine

Update 2

So I feel like I've tracked this down to be an issue specifically in Android on 0.73.9 where dynamic imports import(...) are breaking for lazy loaded screens in react-navigation.

When I change my imports to be top-level everything loads fine. Not sure how to resolve this, but will try to make a reproduction

mobinni commented 1 month ago

The resolution in this thread fixed it https://github.com/facebook/metro/issues/1191

const config = {
  server: {
    rewriteRequestUrl: (url) => {
      return url.replace("&lazy=true", "&lazy=false");
    },
  },
};