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