workspace:*로 엮여있는 프로젝트는 왜 빌드가 되어있을까?
문제 상황
•
apps/service를 실행할 때 packages/ui에서 build나 dev를 실행하지 않으면 에러가 발생합니다.
•
ui의 dist 폴더가 pnpm install 시 생성되지 않습니다.
•
pnpm lint를 실행할 때 build를 실행한 상태와 하지 않은 상태에서 결과가 다릅니다.
왜 그런것인지 이해가 되지 않았습니다.
폴더 구조
•
apps
◦
service
"dependencies": {
"@sc/ui": "workspace:*",
"next": "^13.4.19",
"react": "^18.2.0",
"react-dom": "^18.2.0"
JavaScript
복사
apps/service/package.json
apps/service/node_modules
•
packages
◦
ui
"sideEffects": [
"**/*.css"
],
"main": "./dist/index.mjs",
"types": "./dist/index.d.mts",
"exports": {
".": {
"import": "./dist/index.mjs",
"types": "./dist/index.d.mts"
}
},
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
},
JavaScript
복사
packages/ui/package.json
해결
문제는 turbo.json의 ^build 옵션을 잘못 이해한 것이 원인입니다. ^build 옵션은workspace:*로 묶여있는 프로젝트들을 우선적으로 ^명령어를 실행해준다” 입니다.
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
...
},
"lint": {
"dependsOn": ["^build"],
},
"dev": {
"dependsOn": ["^build"],
...
},
...
}
}
JavaScript
복사
dependsOn: ["^build"]는 workspace:*로 연결된 하위 프로젝트(ex. “@sc/ui”: “workspace:*”)를 먼저 빌드해줍니다. 이로 인해 lint, dev 등의 명령어 실행 전 프로젝트가 정상적으로 동작할 수 있게 됩니다.
packages/ui/package.json의 export 개선
모노레포를 사용할 때, 코드를 직접 빌드해 두어야 하는지에 대한 의문이 생겼습니다. 배포된 코드를 확인해보니, 각 프로젝트가 workspace:*를 통해 다른 프로젝트를 가져올 때, 빌드된 파일이 모듈에 포함되어 있어야 한다는 것을 알게 되었습니다. 하지만 UI에서 작업한 내용을 빌드된 상태로 다른 프로젝트에서 불러서 사용하는 것이 조금 어색하게 느껴졌습니다. 그동안 같은 파일에서 TypeScript 코드를 직접 호출하는 경우를 봐왔기 때문에 더욱 그렇게 느꼈던 것 같습니다.
관련해서 문서를 찾아보던 중 아래 글을 발견했습니다.
결과적으로 지금까지하던건 외부 번들을 위한 코드였음을 알 수 있었습니다.
따라서 아래와 같이 packages/ui/package.json export 방식을 바꿔주었습니다.
"sideEffects": [
"**/*.css"
],
"exports": {
".": "./src/index.ts"
},
]
JavaScript
복사
moduleResolution 에러 해결
There are types at '/Users/ydw0628/midasin/frontend/apps/commerce/node_modules/@sc/ui/src/index.ts', but this result could not be resolved under your current 'moduleResolution' setting. Consider updating to 'node16', 'nodenext', or 'bundler'.ts(2307)문제 보기 (⌥F8)
위와 같은 에러 메시지를 보고, Turbo Repo 예제의 tsconfig에 있는 base.json 항목을 살펴보았습니다.
nodenext와 node16은 require와 import를 모두 지원합니다. 관련 자료를 찾아보니, node와 node10은 CommonJS의 require만 지원하는 것을 알게 되었습니다 .
또한, bundler는 import와 export를 지원하지만 require는 처리하지 않습니다 .
따라서 node를 nodenext로 변경하라는 권장에 따라 base.json을 nodenext로 수정하니 UI 타입 에러가 사라졌습니다 .
참고 링크:
nextjs.json에 있던 옵션에서 에러 해결
Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Next.js",
"extends": "./base.json",
"compilerOptions": {
"plugins": [{ "name": "next" }],
"allowJs": true,
"declaration": false,
"declarationMap": false,
"incremental": true,
"jsx": "preserve",
"lib": ["dom", "dom.iterable", "esnext"],
"module": "esnext",
"noEmit": true,
"resolveJsonModule": true,
"strict": false,
"target": "es5"
},
"include": ["src", "next-env.d.ts"],
"exclude": ["node_modules"]
}
JavaScript
복사
뭔차이가 있는지 설명을 확인했습니다. 이전에는 무지성으로 복사했던 옵션들을 찬찬히 뜯어보니 base.json과 next.json의 옵션들을 수정해줘도 될것으로 판단되어 아래와 같이 수정해줬습니다.
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Next.js",
"extends": "./base.json",
"compilerOptions": {
"plugins": [{ "name": "next" }],
"allowJs": true,
"declaration": false,
"declarationMap": false,
"incremental": true,
"jsx": "preserve",
"lib": ["dom", "dom.iterable", "esnext"],
"module": "esnext",
"moduleResolution": "Bundler",
"noEmit": true,
"resolveJsonModule": true,
"strict": false,
"target": "es5"
},
"include": ["src", "next-env.d.ts"],
"exclude": ["node_modules"]
}
JavaScript
복사
next.json
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Default",
"compilerOptions": {
"composite": false,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"inlineSources": false,
"isolatedModules": true,
"moduleResolution": "NodeNext",
"noUnusedLocals": false,
"noUnusedParameters": false,
"preserveWatchOutput": true,
"skipLibCheck": true,
"strict": true,
"strictNullChecks": true
},
"exclude": ["node_modules"]
}
JavaScript
복사
base.json
참고 자료