Vercel 빌드 에러: Module not found
Vercel 빌드 시 발생하는 Module not found 에러를 해결하는 방법을 알아봅니다.
Vercel 빌드 에러: Module not found
Introduction
Vercel 빌드 시 "Module not found" 에러는 가장 흔한 빌드 에러 중 하나입니다. 이 에러는 모듈을 찾을 수 없다는 것을 의미하며, 다양한 원인으로 발생할 수 있습니다. 이 글에서는 이 에러의 원인을 분석하고 해결하는 방법을 알아보겠습니다.
Environment
- Vercel 프로젝트 (Next.js 14+)
- Node.js 18+
- TypeScript
- monorepo 구조
Problem
빌드 시 발생하는 Module not found 에러:
> Build error occurred
Error: Module not found: Can't resolve '@/components/Button'
Module not found: Can't resolve 'lodash'
Module not found: Can't resolve './utils/helpers'Analysis
Module not found 에러의 주요 원인:
- 경로 지정 오류: import 경로가 잘못됨
- 의존성 누락: package.json에 패키지가 없음
- alias 설정 오류: TypeScript/Next.js alias 설정 문제
- monorepo 환경: 패키지 간 참조 문제
- 대소문자 구분: 파일명 대소문자 불일치
Solution
1. tsconfig.json 경로 설정 확인
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@/components/*": ["./src/components/*"],
"@/lib/*": ["./src/lib/*"],
"@/utils/*": ["./src/utils/*"]
}
}
}2. next.config.js 설정
// next.config.js
const path = require('path');
module.exports = {
webpack: (config, { isServer }) => {
config.resolve.alias = {
...config.resolve.alias,
'@': path.resolve(__dirname, './src'),
'@/components': path.resolve(__dirname, './src/components'),
'@/lib': path.resolve(__dirname, './src/lib'),
};
return config;
},
};3. import 경로 수정
// 잘못된 예시
import Button from '@/components/Button';
import { formatDate } from '@/utils/date';
import { prisma } from '@/lib/prisma';
// 올바른 예시 (파일 확장자 포함)
import Button from '@/components/Button.tsx';
import { formatDate } from '@/utils/date.ts';
import { prisma } from '@/lib/prisma.ts';4. monorepo 패키지 참조
// packages/web/package.json
{
"dependencies": {
"@myapp/ui": "workspace:*",
"@myapp/utils": "workspace:*"
}
}// packages/web/src/app/page.tsx
import { Button } from '@myapp/ui';
import { formatDate } from '@myapp/utils';5. 의존성 설치 확인 스크립트
// scripts/check-dependencies.js
const fs = require('fs');
const path = require('path');
function checkDependencies() {
const packageJson = JSON.parse(
fs.readFileSync(path.join(__dirname, '../package.json'), 'utf8')
);
const allDeps = {
...packageJson.dependencies,
...packageJson.devDependencies
};
const missingDeps = [];
// node_modules 폴더 확인
const nodeModulesPath = path.join(__dirname, '../node_modules');
for (const [dep, version] of Object.entries(allDeps)) {
const depPath = path.join(nodeModulesPath, dep);
if (!fs.existsSync(depPath)) {
missingDeps.push(`${dep}@${version}`);
}
}
if (missingDeps.length > 0) {
console.error('Missing dependencies:');
missingDeps.forEach(dep => console.error(` - ${dep}`));
console.log('\nRun: npm install');
process.exit(1);
}
console.log('All dependencies are installed');
}
checkDependencies();6. Vercel 빌드 로그 분석
# 빌드 에러 상세 확인
vercel build --verbose
# 특정 빌드 확인
vercel inspect --url=https://your-app.vercel.app
# 빌드 히스토리 확인
vercel ls7. 환경 변수 확인
# Vercel 환경 변수 확인
vercel env ls
# 로컬 환경 변수 확인
cat .env.local
# 환경 변수 검증 스크립트
node -e "require('dotenv').config(); console.log(process.env);"8. TypeScript 에러 해결
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}9. 빌드 캐시 문제 해결
# 빌드 캐시 삭제
rm -rf .next
rm -rf .vercel/cache
# node_modules 재설치
rm -rf node_modules
npm install
# 다시 빌드
npm run buildLessons Learned
- 경로 설정: TypeScript와 Next.js의 경로 설정을 일관되게 유지해야 합니다.
- 의존성 관리: 모든 의존성이 package.json에 올바르게 정의되어야 합니다.
- monorepo 설정: monorepo 환경에서는 패키지 간 참조를 올바르게 설정해야 합니다.
- 대소문자: 파일명 대소문자를 일관되게 유지해야 합니다.
- 빌드 캐시: 빌드 문제가 발생하면 캐시를 삭제하고 다시 빌드하는 것이 효과적입니다.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.