typescript 핸드북 학습내용 정리
https://typescript-kr.github.io/pages/the-handbook.html
모듈 해석
모듈 해석 (module resolution)은 컴파일러가 import가 무엇을 참조하는지 알아내기 위해 사용되는 프로세스.
- 첫번째로 모듈을 나타내는 파일의 위치를 찾고 못 찾으면 ambient 모듈을 찾으려고 함. 못 찾으면 오류
상대적 vs 비상대적 모듈 import
상대적 - 경로 지정됨
가져온 파일에 상대적으로 해석되고 ambient 모듈 선언으로 해석 될 수 없음
import Entry from "./components/Entry";
import { DefaultHeaders } from "../constants/http";
import "/mod";
비상대적 - 나머지 전부
baseUrl로 해석되거나, 밑에서 다루게 될 경로 매핑으로 해석될 수 있습니다. ambient 모듈 선언으로도 해석될 수 있음.
외부 의존성을 import할때 비상대적 경로를 사용해
import * as $ from "jquery";
import { Component } from "@angular/core";
모듈 해석 전략
클래식
TS의 디폴트 해석 전략으로 사용됨. 주로 이전 버전과의 호환성을 위해 제공됨
상대적 import
import하는 파일에 상대적으로 해석됨.
소스 파일 /root/src/folder/A.ts안에 import { b } from “./moduleB”`인 경우
/root/src/folder/moduleB.ts
/root/src/folder/moduleB.d.ts
위 경로를 찾음.
비상대적 import
소스 파일 /root/src/folder/A.ts안에 import { b } from "moduleB"인 경우
/root/src/folder/moduleB.ts
/root/src/folder/moduleB.d.ts
/root/src/moduleB.ts
/root/src/moduleB.d.ts
/root/moduleB.ts
/root/moduleB.d.ts
/moduleB.ts
/moduleB.d.ts
위 경로를 찾음
노드
node.js가 모듈을 해석하는 방법
require 함수를 호출해 수행함.
상대경로
var x = require(“./moduleB”);라는 import 문을 포함한 /root/src/moduleA.js의 경우
- /root/src/moduleB.js라는 파일이 존재하는지 확인.
- 만약 “main” 모듈을 지정하는 package.json라는 파일을 포함하고 있으면, /root/src/moduleB 폴더 확인하기. 이 예제에서는, 만약 Node.js가 { “main”: “lib/mainModule.js” }을 포함하는 /root/src/moduleB/package.json파일을 찾았다면, Node.js가 /root/src/moduleB/lib/mainModule.js를 참조
- index.js 라는 파일을 포함하고 있으면, /root/src/moduleB 확인
비상대적 경로
한줄 요약 node_modules에서 찾음
TS가 모듈을 해석하는 방법
ts는 node.js의 런타임 해석전략을 모방함. (ts, tsx, d.ts 등 확장자만 늘어남)
추가 모듈 해석 플래그
- 컴파일 후 소스 파일의 경로와 이름이 일치 하지 않을 수 있음.
- TS 컴파일러는 예상되는 변환을 컴파일러에게 알리기 위한 추가 플래그 세트가 있음
기본 URL
baseUrl을 설정하는 것은 컴파일러에게 어디에서 모듈을 찾을지 알려주는 것
- baseUrl 명령 줄 인수 값 (만약 주어진 경로가 상대적이면, 현재 디렉터리를 기준으로 계산됨)
- 'tsconfig.json’안에 baseUrl 프로퍼티 값 (만약 주어진 경로가 상대적이면, 'tsconfig.json’의 위치를 기준으로 계산됨)
경로 매핑
모듈이 baseUrl 내에 없을때 tsconfig.json에 path 설정
{
"compilerOptions": {
"baseUrl": ".", // "paths"가 있는 경우 반드시 지정되어야함.
"paths": {
"jquery": ["node_modules/jquery/dist/jquery"] // 이 매핑은 "baseUrl"에 상대적임.
}
}
}
여러개의 위치도 매핑이 가능함.
projectRoot
├── folder1
│ ├── file1.ts (imports 'folder1/file2' and 'folder2/file3')
│ └── file2.ts
├── generated
│ ├── folder1
│ └── folder2
│ └── file3.ts
└── tsconfig.json
위 경우 tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"*": [
"*",
"generated/*"
]
}
}
}
rootDir 가상디렉토리
rootDirs을 사용하면, 컴파일러에게 이 가상 디렉토리를 구성하는 roots를 알릴 수 있음.
src
└── views
└── view1.ts (imports './template1')
└── view2.ts
generated
└── templates
└── views
└── template1.ts (imports './view2')
{
"compilerOptions": {
"rootDirs": [
"src/views",
"generated/templates/views"
]
}
}
./#{locale}/messages와 같은 상대 모듈 경로의 일부로 #{locale}와 같은 특수 경로 토큰을 보간하여 빌드 툴이 로케일 전용 번들을 자동으로 생성하는 국제화 시나리오
// ./zh/messages
export default [
"您好吗",
"很高兴认识你"
];
// tsconfig.json
{
"compilerOptions": {
"rootDirs": [
"src/zh",
"src/de",
"src/#{locale}"
]
}
}
'./#{locale}/messages’를 './zh/messages’로 해석
모듈 해석 추적
–traceResolution 를 사용하여 모듈 해적 추적이 가능함
│ tsconfig.json
├───node_modules
│ └───typescript
│ └───lib
│ typescript.d.ts
└───src
app.ts
tsc --traceResolution //컴파일러 호출
출력
======== Resolving module 'typescript' from 'src/app.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
Loading module 'typescript' from 'node_modules' folder.
File 'src/node_modules/typescript.ts' does not exist.
File 'src/node_modules/typescript.tsx' does not exist.
File 'src/node_modules/typescript.d.ts' does not exist.
File 'src/node_modules/typescript/package.json' does not exist.
File 'node_modules/typescript.ts' does not exist.
File 'node_modules/typescript.tsx' does not exist.
File 'node_modules/typescript.d.ts' does not exist.
Found 'package.json' at 'node_modules/typescript/package.json'.
'package.json' has 'types' field './lib/typescript.d.ts' that references 'node_modules/typescript/lib/typescript.d.ts'.
File 'node_modules/typescript/lib/typescript.d.ts' exist - use it as a module resolution result.
======== Module name 'typescript' was successfully resolved to 'node_modules/typescript/lib/typescript.d.ts'. ========
import의 이름과 위치
- ======== ‘src/app.ts’ 에서 ‘typescript’ 모듈 해석. ========
컴파일러가 따르는 전략
- 모듈 해석 종류가 지정되지 않으면, 'NodeJs 사용.
npm 패키지에서 types 로딩
- 'package.json’은 'node_modules/typescript/lib/typescript.d.ts’를 참조하는 ‘types’ 필드 './lib/typescript.d.ts’가 있습니다.
최종 결과
- ======== 모듈 이름 'typescript’는 'node_modules/typescript/lib/typescript.d.ts’로 성공적으로 해석 되었습니다. ========
–noResolve 사용하기
명령줄에 추가하지 않은 파일은 컴파일에 추가하지 않도록 지시함
import * as A from "moduleA" // 성공, 'moduleA'가 명령줄로 전달됨
import * as B from "moduleB" // Error TS2307: Cannot find module 'moduleB.
tsc app.ts moduleA.ts --noResolve
제외 목록에 있는 모듈을 컴파일러가 선택하는 이유
- tsconfig.json은 폴더를 "프로젝트"로 바꿈.
- 제외하고 싶으면 tsconfig.json에서 exclude를 사용
- 포함하고 싶으면 tsconfig.json에서 files 사용
'공부공부 > TS' 카테고리의 다른 글
[typescript 핸드북] 12. 네임스페이스와 모듈 (0) | 2024.02.19 |
---|---|
[typescript 핸드북] 11. 네임스페이스 (1) | 2024.02.19 |
[typescript 핸드북] 09. 모듈 (0) | 2024.02.19 |
[typescript 핸드북] 08. 유틸리티 타입 (0) | 2024.02.19 |
[typescript 핸드북] 07. 제네릭 (0) | 2024.02.19 |