TypeScript
TypeScript는 monorepo에서 훌륭한 도구로, 팀이 JavaScript 코드에 안전하게 타입을 추가할 수 있습니다. 설정에 약간의 복잡성이 있지만, 이 가이드는 대부분의 사용 사례에 대한 TypeScript 설정의 중요한 부분을 안내합니다.
이 가이드는 최신 버전의 TypeScript를 사용한다고 가정하며 해당 버전에서만 사용할 수 있는 일부 기능을 사용합니다. 해당 버전의 기능을 사용할 수 없는 경우 이 페이지의 지침을 조정해야 할 수 있습니다.
tsconfig.json 공유
TypeScript 구성에 일관성을 구축하여 전체 저장소가 훌륭한 기본값을 사용할 수 있고 동료 개발자가 Workspace에서 코드를 작성할 때 무엇을 기대할 수 있는지 알 수 있기를 원합니다.
TypeScript의 tsconfig.json은 TypeScript 컴파일러에 대한 구성을 설정하며 워크스페이스 전체에서 구성을 공유하는 데 사용할 extends 키를 제공합니다.
이 가이드는 예제로 create-turbo를 사용합니다.
기본 tsconfig 파일 사용
packages/typescript-config 내부에는 다양한 패키지에서 TypeScript를 구성하려는 여러 가지 방법을 나타내는 몇 개의 json 파일이 있습니다. base.json 파일은 워크스페이스의 다른 모든 tsconfig.json에 의해 확장되며 다음과 같습니다:
tsconfig options reference
나머지 패키지 만들기
이 패키지의 다른 tsconfig 파일은 extends 키를 사용하여 기본 구성으로 시작하고 Next.js(nextjs.json) 및 React 라이브러리(react-library.json)와 같은 특정 유형의 프로젝트에 맞게 사용자 지정합니다.
package.json 내부에서 Workspace의 나머지 부분에서 참조할 수 있도록 패키지 이름을 지정합니다:
TypeScript 패키지 빌드
구성 패키지 사용
먼저, @repo/typescript-config 패키지를 패키지에 설치합니다:
그런 다음 @repo/typescript-config 패키지에서 패키지에 대한 tsconfig.json을 확장합니다. 이 예제에서 web 패키지는 Next.js 애플리케이션입니다:
패키지에 대한 진입점 만들기
먼저, dist 디렉터리가 있도록 코드가 tsc로 컴파일되었는지 확인합니다. build 스크립트와 dev 스크립트가 필요합니다:
그런 다음, 다른 패키지가 컴파일된 코드를 사용할 수 있도록 package.json에 패키지의 진입점을 설정합니다:
이런 방식으로 exports를 설정하면 여러 장점이 있습니다:
types필드를 사용하면tsserver가src의 코드를 코드 타입의 신뢰할 수 있는 소스로 사용할 수 있습니다. 편집기는 항상 코드의 최신 인터페이스를 최신 상태로 유지합니다.- 위험한 배럴 파일을 만들지 않고도 패키지에 새 진입점을 빠르게 추가할 수 있습니다.
- 편집기에서 패키지 경계를 넘어서는 import에 대한 자동 가져오기 제안을 받을 수 있습니다.
패키지를 게시하는 경우, 컴파일된 코드만 npm에 게시되므로 types에서 소스
코드에 대한 참조를 사용할 수 없습니다. 선언 파일과 소스 맵을 생성하고 참조해야
합니다.
코드베이스 린팅
TypeScript를 린터로 사용하려면 Turborepo의 캐싱과 병렬화를 사용하여 워크스페이스 전체의 타입을 빠르게 검사할 수 있습니다.
먼저, 타입을 검사하려는 패키지에 check-types 스크립트를 추가합니다:
그런 다음, turbo.json에 check-types 작업을 생성합니다. 작업 구성 가이드에 따라 Transit Node를 사용하여 다른 패키지의 소스 코드 변경 사항을 준수하면서 작업을 병렬로 실행할 수 있습니다:


그런 다음, turbo check-types를 사용하여 작업을 실행합니다.
모범 사례
패키지 컴파일에 tsc 사용
Internal Packages의 경우, 가능한 한 TypeScript 라이브러리를 컴파일할 때 tsc를 사용하는 것을 권장합니다. 번들러를 사용할 수는 있지만 필수는 아니며 빌드 프로세스에 추가적인 복잡성을 더합니다. 또한, 라이브러리를 번들링하면 애플리케이션의 번들러에 도달하기 전에 코드가 변형될 수 있어 디버깅하기 어려운 문제가 발생할 수 있습니다.
패키지 경계를 넘어 정의로 이동 활성화
"정의로 이동"은 클릭이나 단축키로 심볼(변수나 함수 등)의 원래 선언이나 정의로 빠르게 이동할 수 있는 편집기 기능입니다. TypeScript가 올바르게 구성되면 Internal Packages 간에 쉽게 이동할 수 있습니다.
Just-in-Time 패키지
Just-in-Time 패키지에서 내보낸 항목은 자동으로 원본 TypeScript 소스 코드로 이동합니다. 정의로 이동 기능이 예상대로 작동합니다.
컴파일된 패키지
컴파일된 패키지에서 내보낸 항목의 정의로 이동 기능이 작동하려면 declaration 및 declarationMap 구성을 사용해야 합니다. 패키지에 이 두 구성을 활성화한 후 tsc로 패키지를 컴파일하고 출력 디렉터리를 열면 선언 파일과 소스 맵을 찾을 수 있습니다.
이 두 파일이 준비되면 편집기가 원본 소스 코드로 이동합니다.
TypeScript 컴파일러 paths 대신 Node.js 서브패스 가져오기 사용
TypeScript 컴파일러의 paths 옵션을 사용하여 패키지에서 절대 가져오기를 만들 수 있지만, 이러한 경로는 Just-in-Time 패키지를 사용할 때 컴파일 실패를 일으킬 수 있습니다. TypeScript 5.4부터 더 견고한 솔루션을 위해 Node.js 서브패스 가져오기를 대신 사용할 수 있습니다.
Just-in-Time 패키지
Just-in-Time 패키지에서는 dist와 같은 빌드 출력이 생성되지 않으므로 imports가 패키지의 소스 코드를 대상으로 해야 합니다.
컴파일된 패키지
컴파일된 패키지에서 imports는 패키지의 빌드된 출력을 대상으로 합니다.
프로젝트 루트에 tsconfig.json 파일이 필요하지 않을 가능성이 높습니다
저장소 구조화 가이드에서 언급했듯이, 도구의 각 패키지를 자체 단위로 취급하려고 합니다. 이는 각 패키지가 프로젝트 루트의 tsconfig.json을 참조하는 대신 사용할 자체 tsconfig.json을 가져야 한다는 것을 의미합니다. 이 방법을 따르면 Turborepo가 타입 검사 작업을 캐시하기가 더 쉬워지고 구성이 단순해집니다.
Workspace 루트에 tsconfig.json을 두고자 할 수 있는 유일한 경우는 패키지에 없는 TypeScript 파일에 대한 구성을 설정하는 것입니다. 예를 들어, 루트에서 실행해야 하는 TypeScript로 작성된 스크립트가 있는 경우 해당 파일에 대한 tsconfig.json이 필요할 수 있습니다.
그러나 Workspace 루트의 변경 사항은 모든 작업이 캐시를 놓치게 하므로 이 방법도 권장되지 않습니다. 대신 해당 스크립트를 저장소의 다른 디렉터리로 이동하세요.
TypeScript 프로젝트 참조가 필요하지 않을 가능성이 높습니다
TypeScript 프로젝트 참조는 워크스페이스에 또 다른 구성 지점과 캐싱 계층을 추가하므로 사용을 권장하지 않습니다. 이 두 가지는 이점이 거의 없으면서 저장소에 문제를 일으킬 수 있으므로 Turborepo를 사용할 때는 피하는 것이 좋습니다.
제한 사항
편집기가 패키지의 TypeScript 버전을 사용하지 않습니다
tsserver는 코드 편집기에서 다른 패키지에 대해 서로 다른 TypeScript 버전을 사용할 수 없습니다. 대신 특정 버전을 발견하여 모든 곳에서 사용합니다.
이로 인해 편집기에 표시되는 린팅 오류와 타입을 검사하기 위해 tsc 스크립트를 실행할 때의 오류가 다를 수 있습니다. 이것이 문제가 되는 경우 TypeScript 종속성을 동일한 버전으로 유지하는 것을 고려하세요.