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