개요
자바스크립트나 타입스크립트 프로젝트에서 모듈이나 컴포넌트를 불러 올 경우 다음과 같은 형태로 모듈이나 컴포넌트를 불러오는 경우를 많이 경험할 수 있다.
import { whereAmI } from "../../../../../../where/the/hell/are/you";
상대 경로와 절대 경로를 사용해서 모듈이나 컴포넌트를 불러오는 방법은 매우 일반적이지만 이보다 더 좋은 방법을 소개하려고 한다.
기존의 문제점
상대 경로
상대 경로 방식으로 모듈을 불러오는 방식은 매우 간편하다는 장점이 있다.
일반적인 IDE에서는 내부 모듈의 위치를 상대 경로로 자동으로 작성해준다.
하지만 모듈을 다른 폴더로 옮길 경우에 해당 모듈을 사용하는 모든 파일의 경로를 수정해야 한다.
물론 이와 같은 경우에도 IDE가 알아서 경로를 수정해 주지만, 규모가 커질수록 파일이 어디에 있는지 찾기 어려워지고 이는 개발자의 코드 리팩토링이 까다로워지는 요인이 된다.
절대 경로
절대 경로 방식은 혼자 개발하는 프로젝트가 아닌 이상 사용할 수 없는 방식이다.
예를 들어 windows로 개발하는 A와 macOS로 개발하는 B는 서로의 절대 경로가 다를 수밖에 없다.
경로 별칭
위와 같은 문제를 해결하기 위해 타입스크립트 프로젝트에서는 경로 별칭을 사용할 수 있다.
경로 별칭은 상대 경로나 절대 경로를 대체할 수 있는 단축된 경로를 의미한다.
경로 별칭을 활용하면 npm에서 내려받은 패키지를 불러오듯이 기억하기 쉬운 이름으로 모듈을 불러올 수 있다.
예를 들어 z라는 모듈을 불러오기 위한 상대 경로와 절대 경로 방식과 경로 별칭 방식의 차이는 다음과 같다.
- 상대 경로와 절대 경로 방식
import { z } from "../../../node_modules/zod";
import { z } from "/Users/John/Projects/our-project/node_modules/zod";
- 경로 별칭 방식
import { z } from "zod";
이처럼 경로 별칭 방식을 사용하면 사전에 미리 정의해 둔 별칭으로 간결하게 모듈을 불러올 수 있다.
현업 프로젝트에서는 별칭 경로를 한 눈에 알아볼 수 있도록 ~, @, #, $와 같은 특수 기호를 앞에 붙이는 경우가 많다.
// 상대 경로와 절대 경로 방식
import { add } from "/Users/John/Projects/src/common/utilities/math";
import { add } from "../../../../common/utilities/math";
// 경로 별칭 방식
import { add } from "~utils/math";
import { add } from "@utils/math";
import { add } from "#utils/math";
import { add } from "$utils/math";
경로 별칭 등록 방법
타입스크립트 프로젝트에서 경로 별칭은 tsconfig.json 파일의 paths 옵션을 통해서 등록할 수 있다. 경로 별칭은 키(key)로 모듈 경로를 값(value)으로 하는 객체를 paths 옵션에 설정해주면 된다.
{
"compilerOptions": {
"paths": {
"#utils/*": ["./src/common/utilities/*"],
"#math-utils/*": ["./src/common/utilities/math/*"],
}
}
}
위 설정에서는 ./src/common/utilities/ 까지의 경로를 #utils/ 로 선언하였고 ./src/common/utilities/math/ 경로를 #math-utils/ 로 선언하였다.
사용 예제는 다음과 같다.
import { shuffle } from "#utils/random";
// import { shuffle } from "<프로젝트 최상위 경로>/src/common/utilities/random";
import { add } from "#math-utils";
// import { add } from "<프로젝트 최상위 경로>/src/common/utilities/math";
규모가 크지 않은 프로젝트에서의 경로 별칭 사용
규모가 크지 않은 프로젝트에서는 상대 경로나 절대 경로만을 피하고 싶을 수 있다.
tsconfig.json의 baseUrl 옵션을 사용하면 상대 경로나 절대 경로를 피할 수 있다.
{
"compilerOptions": {
"baseUrl": "./src"
}
}
위와 같이 설정하면 src 폴더 하위에 존재하는 모듈은 상대 경로를 적지 않아도 된다.
이를 path와 응용하면 다음과 같이 작성할 수 있다.
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"#utils/*": ["common/utilities/*"],
"#math-utils/*": ["common/utilities/math/*"]
}
}
}
위에서 설정해둔 내용에서 ./src가 빠진 모습을 볼 수 있다.
이렇게 설정해두면 타입스크립트 내부에서는 두 단계로 경로 맵핑이 일어난다.
첫 번째로 baseUrl로 맵핑이 일어나고 두 번째로 paths 속성에서 맵핑이 일어난다.
새로운 디렉토리가 추가될 때 마다 설정하기 귀찮을 때
위에서 utils, math-utils 폴더를 맵핑하는 예제를 살펴보았다.
하지만 실제 프로젝트를 진행할 땐 utils, redux, components, requests, types 등 수많은 폴더를 관리해야 할 수 있다.
폴더를 생성할 때 마다 경로 별칭을 사용하는 것은 매우 귀찮은 작업이 될 수 있다.
이를 해결하기 위한 방법이 있다.
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"#/*": ["*"]
}
}
}
위와 같이 설정해 두면 #/만 앞에 붙히는 것으로 src 내의 모든 모듈을 불러올 수 있다.
향후 프로젝트에선 경로 별칭 방법을 사용하여 유지보수와 리팩토링이 용이하고 이해하기 쉬운 코드를 작성하는 데 도움이 되었으면 좋겠다.
타입스크립트 5.8의 경로 정규화 및 프로그램 빌드 최적화
경로 정규화 과정
보통 react 프로젝트에서 import한 모듈은 다음과 같이 작성된다.
import Title from './components/title/Title';
프로젝트 빌드를 수행할 땐 경로가 다음과 같은 과정으로 바뀐다.
우선 Title 컴포넌트는 상대 경로로 작성되어 있다.
컴파일러는 Title 컴포넌트를 찾아내려고 시도하며, 이 과정에서 경로 정규화가 진행된다.
상대 경로를 문자열 배열로 분할한 후 상대적인 부분을 기준으로 정규화한다.
해당 코드에서 path.replace(/\\.\\//g, "/")는 경로 중간에 있는 ./ 부분을 슬래시(/)로 바꾼다.
path.replace(/\\.\\.\\//g, "")는 경로에 포함된 ../를 없앤다.
즉 프로젝트를 컴파일 할때 시작 경로가 ./로 작성되었다면 이를 /components/title/Title 로 바꾼다.
../ 의 경우에는 프로젝트의 상위 디렉토리로 이동을 하게 된다.
프로젝트를 빌드할 때 컴파일러는 이러한 상대 경로를 깔끔하게 처리하기 위해 경로 정규화를 진행한다.
타입스크립트는 프로젝트 빌드 시 경로 정규화 과정에서 문자가 . 인지 ..인지 확인하여 처리를 수행하였다.
하지만 이 과정에서 길이가 1이고 문자가 . 이 아님에도 컴파일 시 문자가 .. 인지 확인하는 문제가 발생하였다.
기능상 큰 문제는 없지만 프로젝트가 커질 경우 해당 작업 때문에 빌드 성능이 떨어질 수 있다.
때문에 5.8 버전에서는 해당 작업을 수행하지 않음으로써 빌드 성능을 높였다.
타입스크립트 5.8 버전은 프로젝트 구조를 수정하지 않으면 tsconfig.json을 다시 확인하지 않는다.
프로젝트 컴파일 시 경로를 정규화 할 때, 타입스크립트 컴파일러는 tsconfig.json의 baseUrl 옵션과 paths 옵션을 확인한 후 정규화를 진행한다.
5.8 버전 이상부터는 프로젝트 구조를 바꾸지 않으면 tsconfig.json을 다시 확인하지 않는다.
참고문헌
본 글은 다음 문헌들을 참고하였습니다.
https://www.daleseo.com/tsconfig-path-mapping/
타입스크립트의 경로 맵핑 (baseUrl, paths)
Engineering Blog by Dale Seo
www.daleseo.com
https://velog.io/@typo/announcing-typescript-5-8-beta#프로그램-로드와-업데이트될-때의-최적화
[번역] 타입스크립트 5.8 베타를 소개합니다
타입스크립트 5.8 베타 버전이 1월 29일에 릴리즈되었습니다. 이번 버전에서는 특히 조건부 반환 타입을 체크하는 데에 있어 두드러지는 변경점이 있다고 합니다. 한번 확인해보세요!
velog.io
https://github.com/microsoft/TypeScript/pull/60812
Write path normalization without array allocations by andrewbranch · Pull Request #60812 · microsoft/TypeScript
Related: #60633 Alternative to #60755 Despite the good benchmarks, I didn’t see any measurable impact in real-world updateGraphWorker duration on my M2 Mac Mini. However, since that was a GC hot sp...
github.com
'기타' 카테고리의 다른 글
Linux 해외 아이피 접속 차단을 위한 ufw 방화벽 설정 방법 (3) | 2025.03.02 |
---|---|
Typescript 5.8.0의 조건부 반환 타입 검사 기능 (4) | 2025.02.24 |
라즈베리파이 외부 ssh 접속을 위한 포트포워딩 (0) | 2025.02.01 |