대규모 Nx 프로젝트 점진적으로 migration 하기 프로젝트..😴
현재 버전
- 14.4.2
현재 버전의 문제점
- 워크스페이스 단일 package.json 을 사용한다 (앱/라이브러리 모두가 공유함)
- 빌드 속도가 느리고, 메모리가 잘 터진다.
18^ 로 마이그레이션 할 시 얻는 이점
- 증분 빌드 최적화 강화
- 일부 빌드 과정에 esbuild 포함
- 캐싱 매커니즘도 강화 됨
- 리모트캐싱 개선 (nx cloud)
- 빌드 프로세스 중 메모리 사용을 최적화 하여 대규모 프로젝트에서 안정적인 성능을 제공함.
TODO
- 요걸 돌리고 (워크스페이스 전체 마이그레이션 적용)
npx nx migrate @nrwl/workspace@15.8.9
yarn install
npx nx migrate --run-migrations
- 아래의 점진적 마이그레이션 코드를 돌린다.
- nx cloud 설정 관련해서 찾아본다.
돌리기 전에 nx.json
에 아래 필드 추가줌
"projects": {
"editor": {
"tags": ["needs-upgrade"]
}
},
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const nxJsonPath = path.resolve(__dirname, '../../nx.json');
const packageJsonPath = path.resolve(__dirname, '../../package.json');
const { projects } = require(nxJsonPath);
const packageJson = require(packageJsonPath);
const targetNxVersion = '15.8.9';
const projectsToUpgrade = Object.entries(projects)
.filter(([, config]) => config.tags.includes('needs-upgrade'))
.map(([name]) => name);
projectsToUpgrade.forEach((project) => {
console.log(`Upgrading ${project}...`);
// NX 버전만 업그레이드
execSync(`npx nx migrate @nrwl/workspace@${targetNxVersion}`, { stdio: 'inherit' });
// 의존성 업데이트 (Next.js 버전 유지)
updateDependencies();
// 마이그레이션 실행
execSync(`npx nx migrate --run-migrations`, { stdio: 'inherit' });
// 빌드 및 테스트
execSync(`nx build ${project}`, { stdio: 'inherit' });
execSync(`nx test ${project}`, { stdio: 'inherit' });
// 태그 업데이트
updateProjectTag(project, 'upgraded-to-nx15');
console.log(`${project} upgraded successfully.`);
});
function updateDependencies() {
const newPackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
// NX 관련 패키지만 업데이트
Object.keys(newPackageJson.dependencies).forEach(dep => {
if (dep.startsWith('@nrwl/') || dep === 'nx') {
newPackageJson.dependencies[dep] = targetNxVersion;
}
});
Object.keys(newPackageJson.devDependencies).forEach(dep => {
if (dep.startsWith('@nrwl/') || dep === 'nx') {
newPackageJson.devDependencies[dep] = targetNxVersion;
}
});
// Next.js 버전 유지
if (newPackageJson.dependencies.next) {
newPackageJson.dependencies.next = '12.3.4';
}
fs.writeFileSync(packageJsonPath, JSON.stringify(newPackageJson, null, 2));
execSync('yarn install', { stdio: 'inherit' });
}
function updateProjectTag(project, newTag) {
const nxJson = require(nxJsonPath);
nxJson.projects[project].tags = [newTag];
fs.writeFileSync(nxJsonPath, JSON.stringify(nxJson, null, 2));
}
문제점
- nx 16 버전 이상부터는 next.js 13 이상에 맞춰서 호환되고 있음
- nx 자체는 12 버전도 지원해주기는 하는데, 문제는 nrwl/next 요 플러그인이 문제임
- nx 를 19버전으로 쓰려면 해당 플러그인도 19 버전으로 맞춰줘야하는데 그럴 경우 nrwl/next 플러그인의 withNext 동작과 next 12 버전이 호환되지 않음 (트랜스파일링 관련)
- nrwl/next 19 버전 플러그인의 peer dep 은 next: 14 이상임
- next13 부터는 transpileModules 필드가 next.config.js 에 추가되었고, nrwl/next 에서 요걸 알아서 처리해줌
- 그런데, next12 에는 해당 필드가 없고, 모듈 트랜스파일 처리를 이전버전의 nrwl/next 에서 해줬던 것임 😭
그 외 개선 가능 부분
- next.config.js 중복 설정 plugin 으로 중복제거
해결방법 (시도중..)
- (장기적으로) Nx 와 함께 앱 내의 Next.js 들도 모두 최신버전으로 마이그레이션 한다.
- 가장 이상적이긴 하나, next 13버전 이상이 정말 필요한가?
- 그렇다고 next 12 를 유지하기 위해서 Nx 버전을 구버전으로 유지하는게 맞을까?
- 1번을 위해서는 일단 Nx는 버전업해두고 트랜스파일링 설정을 별도로 커스터마이징 처리한다.
- 해당 작업은 이전 nwrl/next 의 withNext 함수 내부에서 처리되었던 로직이다.
- Nx 를 사용하지 않을 경우 next-transpile-module 과 같은 패키지를 하나 두어서 처리했던걸로 보인다. (해당 패키지는 현재 관리되고 있지 않다.)
- 따라서 커스텀 설정을 해줘야할 것 같은데 nx 플러그인 등을 사용해서 모든 next.config.js 에 웹팩 트랜스파일설정 추가하도록 해주면 되지 않을까?