문제 1
- 문제 상황: expo app을 추가했더니 특정 모듈을 찾지 못한다는 오류가 발생했다.
- 원인: pnpm의 symlink 방식 때문이며, expo는 이를 해석하지 못하기 때문이다.
- 해결 방법: 이를 해결하기 위해서는 metro 설정을 해주면 된다.
코드: 모노레포 루트의 node_modules를 탐색하도록 설정한다.
const { getDefaultConfig } = require('expo/metro-config');
const path = require('path');
const projectRoot = __dirname;
const monorepoRoot = path.resolve(projectRoot, '../..');
const config = getDefaultConfig(projectRoot);
// 모노레포 루트의 node_modules도 탐색하도록 설정
config.watchFolders = [monorepoRoot];
config.resolver.nodeModulesPaths = [
path.resolve(projectRoot, 'node_modules'),
path.resolve(monorepoRoot, 'node_modules'),
];
// react / react-dom / react-native는 앱의 node_modules에서만 resolve하여 단일 인스턴스 보장
const singleInstancePackages = ['react', 'react-dom', 'react-native'];
config.resolver.resolveRequest = (context, moduleName, platform) => {
for (const pkg of singleInstancePackages) {
if (moduleName === pkg || moduleName.startsWith(pkg + '/')) {
return {
filePath: require.resolve(moduleName, { paths: [projectRoot] }),
type: 'sourceFile',
};
}
}
return context.resolveRequest(context, moduleName, platform);
};
module.exports = config;
문제 2
- 문제 상황: react-lucide를 사용하는 코드에서 타입 에러가 발생한다.
- 원인: 루트 node_modules의 .pnpm에 @types/react@18과 react@19이 공존하고, lucide-react는 @types/react@19를 resolve하고, 이를 사용하는 패키지는 @types/react@18에 의존하는데, 이 둘이 충돌해 발생한 문제이다.
- lucide-react는 devDep에 18을 명시하지만, 이는 라이브러리를 사용하는 패키지에서 사용하는 버전이 아님.
- 해결 방법: .npmrc에 node-linker=hoisted를 설정해서 루트에서는 하나의 의존성만 관리하도록 한다. → lucide-react는 루트의 @types/react@18을 resolve한다.
문제 3
- 문제 상황: .npmrc에
node-linker=hoisted를 설정하면 pnpm의 장점(유령 의존성 해결, strict node_modules 구조)이 희석된다.
- 해결 방법: 모노레포 내 모든 패키지의 react버전을 19로 통일시킨다.