react-native-mask-segment-c.../example/metro.config.js

56 lines
2.0 KiB
JavaScript
Raw Normal View History

const path = require('path');
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
/**
* Metro configuration for the example app.
*
* 关键目标 monorepo / "file:.." / npm link 场景下保证所有带原生/JSI/Fabric 代码的
* peer 依赖都只解析到 **example/node_modules** 下的那一份
*
* 重复解析会导致各种类似问题
* - SkiaPictureView config getter undefined
* - createAnimatedNode: Animated node[...] already exists (Reanimated)
* - 各种 View 注册冲突Invalid hook call
*
* 维护原则凡是 package.json peerDependencies 里声明的且包含原生代码的都必须在这里强制单例
*/
const parentRoot = path.resolve(__dirname, '..');
const exampleNodeModules = path.resolve(__dirname, 'node_modules');
// 必须单例的依赖列表(来自本库的 peerDependencies + 常见会引发冲突的)。
// 以后新增 peer 依赖时,记得同步更新这里。
const singletonPackages = [
'react',
'react-native',
'react-native-reanimated',
'@shopify/react-native-skia',
'react-native-gesture-handler',
'react-native-fast-opencv',
'react-native-safe-area-context',
'react-native-fs',
// 可选 peer
'react-native-image-picker',
];
const config = {
watchFolders: [parentRoot],
resolver: {
nodeModulesPaths: [exampleNodeModules],
// 方式一最强extraNodeModules 强制别名
// 让 import 'xxx' 永远拿到 example/node_modules 里的实例
extraNodeModules: singletonPackages.reduce((acc, pkg) => {
acc[pkg] = path.resolve(exampleNodeModules, pkg);
return acc;
}, {}),
// 方式二双保险blockList 完全禁止 Metro 去父目录的 node_modules 里找这些包
blockList: singletonPackages.map(
(pkg) => new RegExp(`/MaskSegmentApp/node_modules/${pkg.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/`),
),
},
};
module.exports = mergeConfig(getDefaultConfig(__dirname), config);