The example/metro.config.js file uses a specific configuration to handle peer dependencies in a monorepo-like structure. It ensures that only one version of each peer dependency is loaded by blocking the versions located in the root node_modules and aliasing them to the versions found in the example/node_modules directory via extraNodeModules and blockList.
const path = require("path");
const pkg = require("../package.json");
const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");
const escape = require("escape-string-regexp");
const peerDependencies = Object.keys(pkg.peerDependencies);
const root = path.resolve(__dirname, "..");
const projectNodeModules = path.join(__dirname, "node_modules");
const rootNodeModules = path.join(root, "node_modules");
// Block root peer dependencies to prevent multiple versions being loaded
const blockList = peerDependencies.map(
(name) => new RegExp(`^${escape(path.join(rootNodeModules, name))}\\/.*$"`),
);
// Alias peer dependencies to the local example node_modules
const extraNodeModules = peerDependencies.reduce((acc, name) => {
return { ...acc, [name]: path.join(projectNodeModules, name) };
}, {});
const config = {
projectRoot: __dirname,
watchFolders: [root],
resolver: { blockList, extraNodeModules },
};
module.exports = mergeConfig(getDefaultConfig(__dirname), config);