1const { createMetroConfiguration } = require('expo-yarn-workspaces');
2const path = require('path');
3
4const baseConfig = createMetroConfiguration(__dirname);
5
6if (process.env.EXPO_USE_EXOTIC) {
7  // Use the custom transformer when exotic is enabled.
8  baseConfig.transformer.babelTransformerPath = require.resolve('./metro.transformer.js');
9}
10
11// To test NCL from Expo Go, the react-native js source is from our fork.
12const reactNativeRoot = path.join(__dirname, '..', '..', 'react-native-lab', 'react-native', 'packages', 'react-native');
13
14module.exports = {
15  ...baseConfig,
16
17  // NOTE(brentvatne): This can be removed when
18  // https://github.com/facebook/metro/issues/290 is fixed.
19  server: {
20    ...baseConfig.server,
21    enhanceMiddleware: (middleware) => {
22      return (req, res, next) => {
23        // When an asset is imported outside the project root, it has wrong path on Android
24        // This happens for the back button in stack, so we fix the path to correct one
25        const assets = '/node_modules/@react-navigation/elements/src/assets';
26
27        if (req.url.startsWith(assets)) {
28          req.url = req.url.replace(assets, `/assets/../..${assets}`);
29        }
30
31        return middleware(req, res, next);
32      };
33    },
34  },
35
36  resolver: {
37    ...baseConfig.resolver,
38    assetExts: [...baseConfig.resolver.assetExts, 'kml'],
39    blockList: [
40      ...baseConfig.resolver.blockList,
41
42      // Because react-native versions may be different between node_modules/react-native and react-native-lab,
43      // metro and react-native cannot serve duplicated files from different paths.
44      // Assuming NCL only serves for Expo Go,
45      // the strategy here is to serve react-native imports from `react-native-lab/react-native` but not its transitive dependencies.
46      // That is not ideal but should work for most cases if the two react-native versions do not have too much difference.
47      // For example, `react-native-lab/react-native/node_modules/@react-native/polyfills` and `node_modules/@react-native/polyfills` may be different,
48      // the metro config will use the transitive dependency from `node_modules/@react-native/polyfills`.
49      /\bnode_modules\/react-native\//,
50      /\breact-native-lab\/react-native\/node_modules\b/,
51    ],
52  },
53  serializer: {
54    ...baseConfig.serializer,
55    getModulesRunBeforeMainModule: () => [
56      require.resolve(path.join(reactNativeRoot, 'Libraries/Core/InitializeCore')),
57    ],
58    getPolyfills: () => require(path.join(reactNativeRoot, 'rn-get-polyfills'))(),
59  },
60};
61