타입스크립트 프로젝트 옵션 설정하기
Intro
타입스크립트 컴파일러
- 보다 큰 프로젝트를 사용하기 위해 편의성 개선을 위한 컴파일러 설정하기
시계 모드 사용
현재 개발 환경에서 변경사항이 있는 경우 이를 자바스크립트로 컴파일해 런타임 환경에서 작동하도록 아래와 같은 명령을 수동으로 입력하고 있다.
tsc app.ts
위 과정을 파일이 변경될 때마다 컴파일되도록 반영하고 싶다면 관찰모드를 이용한다. 아래 명령을 입력하면 해당 파일에 변경사항이 있는 경우 컴파일이 진행된다.
tsc app.ts -w
다수의 파일 자동 컴파일하기
아래와 같이 html 파일에서 다수의 스크립트를 사용하는 경우 다수의 파일을 컴파일할 수 있도록 해보자.
<script src="app.js" defer></script>
<script src="app2.js" defer></script>
아래와 같이 파일명을 지정하지 않은채 컴파일 명령을 입력한다.
tsc
혹은 프로젝트를 타입스크립트 프로젝트로 지정한다. 이 커맨드가 실행되는 폴더의 모든 파일을 인식하게 된다.
tsc --init
이후 프로젝트내 tsconfig.json
파일이 생성된다. 이 파일은 타입스크립트가 관리해야할 파일이 포함된 프로젝트, 모든 하위 폴더를 참고하기 위한 파일이다.
이후에 컴파일 명령 혹은 관찰 모드 커맨드를 입력하면 프로젝트내 모든 .ts
파일을 감지해 변경사항이 있는 경우 컴파일을 진행한다.
tsconfig 설정하기
프로젝트내 생성된 tsconfig.json
파일은 프로젝트내 파일 제외/추가 혹은 컴파일 대상을 설정하는 타입스크립트 설정 파일이다.
파일 포함 및 제외하기
exclude
tsconfig.json
를 열고 exclude
옵션을 이용할 수 있다. 와일드 카드(_)를 이용할 수 있는데 , _.dev.ts
라는 확장자로 exclude
옵션에 포함시킨 경우 .dev.ts
로 끝나는 모든 파일을 제외한다. 모든 폴더에서 적용할 경우\*_/_.dev.ts
를 입력한다.
// tsconfig.json
"exclude": [
"node_modules" // would be the default
]
기본적으로 라이브러리 폴더인 node_modules
는 설정상 자동으로 제외된다.
include
// tsconfig.json
"include": [
"app.ts"
]
만일 위와 같이 include
옵션에 app.ts만 정의한 경우 app.ts 변경사항이 발견된 경우에만 컴파일되며 다른 *.ts
파일을 컴파일되지 않는다.
필요한 파일만 지정해 컴파일할 수 있다. 이와 같이 exclude
와 include
를 함께 사용하면 include
가 필터링된다.
기본적으로 exclude
옵션만 이용한다.
files
include
와 다소 비슷한 files
옵션도 있는데, include
는 제외하고자 하는 항목을 전체 폴더를 지정하지만 files
는 컴파일하고자 하는 개별 파일만을 지정할 수 있다.
// tsconfig.json
"files": [
"app.ts"
]
컴파일 대상 설정하기
compilerOptions
옵션은 타입스크립트 코드가 컴파일되는 방식을 관리한다.
target
// tsconfig.json
"compilerOptions": {
"target": "es5"
}
해당 옵션은 기본적으로 설정되어 있고 어떤 자바스크립트 버전으로 컴파일할 것인지 설정한다.
es5
의 경우 let
, const
가 포함되지 않으므로 컴파일 후 var
로 대체될 것이다.
이와 같은 점으로 타입스크립트는 이전 브라우저에서도 작동하는 코드를 생성할 수 있다. target
을 지정하지 않으면 타입스크립트는 번호가 없는 es만 컴파일하므로 이전 버전도 지원할 수 있다.
lib
lib
옵션을 사용 이전에 이해할 사항이 있다. 아래와 같이 타입스크립트에서도 dom
에 접근하여 이벤트를 생성할 수 있다.
// app.ts
const button = document.querySelector('button')!;
// 타입스크립트는 런타임 상황에서 작동하지 않으므로. 위와 같은 dom이 존재하는지 확인할 수 없다.
// ! 는 기본적으로 버튼 이라는 개체가 존재하니 값이 반환될 것이라고 타입스크립트에게 알려준다
button.addEventListener('click', () => {
console.log('클릭!');
})
다시말하지만 타입스크립트는 컴파일 이후 자바스크립로 변경되어 브라우저에서 작동하게 된다. 즉 타입스크립트는 브라우저를 위해 작성하지 않는다.
위와 같이 작성 후 컴파일을 해보면 정상적으로 컴파일된것을 확인할 수 있다. 어떻게 타입스크립트가 document
, const
변수가 존재하는것을 타입스크립트가 알 수 있을까?
또한 querySelector
메소드가 존재하는 객체를 포함하는것을 어떻게 알 수 있을까, 이는 lib
옵션때문이다.
// tsconfig.json
"compilerOptions": {
// "lib": [],
}
lib
설정이 안 되어 있다면 기본 설정은 target
옵션에 의지한다. es6
로 설정한 경우 es6
에서 사용가능한 옵션이 전역으로 타입스크립트에 적용된다.
즉 dom과 같은 자바스크립트 API를 사용할 수 있다. 기본으로 lib
옵션은 주석처리 되어 있다.
// tsconfig.json
"compilerOptions": {
"lib": [
"dom",
"es6",
"dom.iterable",
"scripthost"
],
}
위와 같이 target
옵션에 의지하지 않고 선택적으로 API를 선택해 타입스크립트 프로젝트에 적용할 수 있다.
위 옵션 4가지는 주석 처리된 경우 target
옵션에 의지할 때 적용되는 API와 동일하다.
allow
allowJS
옵션과 checkJS
옵션은 주로 같이 사용되며 타입스크립트가 자바스크립트 파일을 컴파일할 수 있도록 도와준다.
.ts
로 끝나지 않는 파일도 컴파일할 수 있게된다.
checkJS
옵션을 사용하면 타입스크립트는 컴파일을 수행하지 않고 구문 검사를 진행하고 잠재적 에러를 보고한다.
.ts
파일에서 변환된 .js
파일에 대해 컴파일을 두 번 수행할 필요가 없으므로 기본적으로 주석처리되어있다.
보통 타입스크립트를 사용하지 않는 프로젝트 환경에서 사용한다.
// tsconfig.json
"compilerOptions": {
"allowJs": true,
"checkJs": true,
}
sourceMap
sourceMap
옵션은 디버깅 작업과 개발에 유용하다.
// tsconfig.json
"compilerOptions": {
"sourceMap": true
}
sourceMap
옵션을 true
로 설정한 후 컴파일하게되면 .js
파일과 함께 js.map
파일도 생성된다.
// app.js.map
{"version":3,"file":"app.js","sourceRoot":"","sources":["app.ts"],"names":[],"mappings":";AAAA,IAAM,QAAQ,GAAG,YAAY,CAAC;AAE9B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC"}
map
파일은 다리 역할을 하며 입력 파일에 자바스크립트 파일을 연결하는 브라우저와 개발자도구 간의 다리 역할을 한다.
sourceMap
옵션을 활성화하면 개발자 도구탭에 Sources
탭에서도 타입스크립트 파일을 확인할 수 있다. 사용하지 않는다면 .js
파일만 포함된다.
장점은 개발자도구에서 자바스크립트 파일처럼 타입스크립트 파일도 개발자도구 디버그 모드 사용이 가능하다는 것이다. 종단점을 선택할 수 있고 일반 자바스크립트처럼 디버깅 모드 이용이 가능하다.
rootDir 및 outDir
rootDir
, outDir
옵션으로 컴파일 대상 경로를 설정할 수 있다.
outDir
프로젝트 규모가 확장됨에 따라 소스 파일을 관리해야하는데 기본적으로 파일 저장시 루트에는 저장하지 않으며 하위 폴더인 src
폴더와 dist
폴더를 더 자주 사용한다.
dist
폴더는 보통 컴파일이 완료된 파일을 보관하며 src
폴더는 개발중인 소스 파일이 보관된다.
다음과 같이 outDir
옵션을 이용해 컴파일이 완료된 파일의 위치를 설정할 수 있다. 아래와 같이 설정했다면 컴파일된 소스 파일을 dist
폴더내 저장된다.
// tsconfig.json
"compilerOptions": {
"outDir": "./dist"
}
컴파일 후dist
폴더내 저장된다. 이때 폴더 경로또한 그대로 복사되어 생성된다.
rootDir
rootDir
옵션으로 루트 디렉토리를 설정하여 컴파일이되는 경로를 설정할 수 있다. 아래의 rootDir
옵션과 같이 설정한 경우 컴파일을 하되, src
내 타입스크립트 파일만 dist
폴더에 저장된다.
// tsconfig.json
"compilerOptions": {
"rootDir": "./src"
}
다음과 같이 컴파일 후 src
폴더내 존재하던 파일만 dist
폴더에 저장된다.
removeComments
removeComments
옵션을 true
로 설정한 경우 컴파일과정에서 소스 코드내 주석은 제외된채로 생성된다.
// tsconfig.json
"compilerOptions": {
"removeComments": true
}
downlevelIteration
코드를 이전 버전의 자바스크립트로 컴파일하고 for 루프로 작업해 컴파일 과정에서 보다 정확하게 수행할 수 있다.
// tsconfig.json
"compilerOptions": {
"downlevelIteration": true
}
컴파일 오류 시 파일(js) 생성 중단하기
기존 타입스크립트 파일은 컴파일시 에러 유무의 상관없이 js 파일로 생성되었다. 이렇게 생성된 js파일은 브라우저에서 런타임시 오류가 발생한다.
noEmitOnError
noEmitOnError
옵션의 기본값은 false
다. 즉 에러 유무의 상관없이 컴파일 후 js
파일을 생성한다.
만일 true
로 설정하는 경우 타입스크립트 소스 에러 발생 후 컴파일시 js
파일이 생성되지 않는다.
// tsconfig.json
"compilerOptions": {
"noEmitOnError": true
}
Strict 컴파일
strict
옵션은 아래 주석 처리된 7가지 모든 strict
관련 옵션을 관리한다.
strict
옵션을 true
로 설정한 경우 모든 아래 7개의 strict
검사 옵션을 모두 사용할 수 있다. 개별적으로 옵션을 설정할 경우
strict
관련 옵션을 개별적으로 true 혹은 false
설정하여 검사 옵션을 지정할 수 있다.
//tsconfig.josn
"compilerOptions": {
"strict": true,
// "noImplicitAny": true,
// "strictNullChecks": true,
// "strictFunctionTypes": true,
// "strictBindCallApply": true,
// "strictPropertyInitialization": true,
// "noImplicitThis": true,
// "alwaysStrict": true,
}
noImplicitAny
noImplicitAny
는 더 나은 코드를 작성하는데 도움을 준다. noImplicitAny
옵션을 true
로 사용한 경우 컴파일시 함수의 매개변수 타입이 any
타입인 경우
에러를 발생시킨다. 함수 생성시점에서 해당 값으로 어떤 결과가 나타날지 추론할 수 없기 때문이다.
단 변수의 경우는 타입을 명시적으로 지정하지 않더라고 생성 시점의 타입을 추적하기 때문에 이러한 에러가 발생하지 않는다.
// analytics.ts
let logged; // any 타입.
function sendAnalytics(data: string){
// 함수의 매개변수 타입을 지정하지 않고 후에 함수 호출시 값을 저장하는 경우
// 호출 시점 보다 함수가 생성되는 시점이 먼저 발생한다. 함수 생성 시점에는 어떤 결과가 나타날지 알 수 없다.
// 때문에 함수의 경우 매개변수 타입을 명확히 지정해야한다.
console.log(data);
logged = true; // 단 변수의 경우 타입을 명시적으로 지정하지 않더라도 생성단계에서 any로 지정되어 에러가 발생하지 않는다.
}
sendAnalytics('The Data');
noImplicitAny
옵션을 true
로 설정한 경우에 함수의 매개변수 타입을 지정하지 않는다면 아래와 같이 에러를 발생시킨다. false
로 설정한 경우 에러를 발생시키지 않는다.
strictNullChecks
strictNullChecks
는 아래와 같은 dom
과 같은 경우를 예로 들 수 있다. 만일 아래 코드와 같이 작성 후 컴파일 한다면 에러를 발생시킨다. 버튼의 유무를 확인할 수 없기 때문이다.
null
값을 잠재적으로 가질 수 있는 값을 컴파일시 알려준다. 타입스크립트는 html 페이지를 알지 못하므로 존재 유무를 알 수 없다.
// app.ts
const button = document.querySelector('button');
button.addEventListener('click', () =>{
console.log('Clicked!');
})
strictNullChecks
옵션을 false
로 설정하면 아래와 같은 에러가 발생하지 않는다.
에러를 발생시키지 않도록 아래와 같이 코드를 수정할 수 있다.
// app.ts
// [1] !로 해당 값은 잠재적 null을 가지지 않는다고 명시해주어야한다.
const button = document.querySelector('button')!;
// [2] if 문으로 존재 유무를 파악한다.
if(button){
button.addEventListener('click', () =>{
console.log('Clicked!');
})
}
strictBindCallApply
strictBindCallApply
옵션은 호출 함수가bind
,call
,apply
중 무엇에 해당하는지 확인 후 함수에 적용되었는지 검사한다.
만일 아래와 같이 매개변수를 정확히 전달하지 않은 경우 에러가 발생한다. 실수를 방지해준다.
// app.ts
const button = document.querySelector('button')!;
function clickHandler(message: string) {
console.log("Clicked!" + message);
}
if(button) {
button.addEventListener('click', clickHandler.bind(null, "You're welcome!");
button.addEventListener('click', clickHandler.bind(null));
}
alwaysStrict
컴파일 시 strict
모드를 사용한 자바스크립트 파일을 생성한다.
// app.js
"use strict";
const button = document.querySelector('button');
function clickHandler(message) {
console.log("Clicked!" + message);
}
if (button) {
button.addEventListener('click', clickHandler.bind(null));
}
그외
strictPropertyInitialization
, strictFunctionTypes
옵션은 클래스 부분과 이어지므로 후에 설명한다.
코드 품질 옵션
잘못된 변수 사용에 대한 에러를 아래와 같은 옵션으로 검사한다. 선언되었지만 사용되지 않거나
//tsconfig.josn
"compilerOptions": {
/* Additional Checks */
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "noImplicitReturns": true,
// "noFallthroughCasesInSwitch": true,
}
noUnusedLocals
noUnusedLocals
옵션은 코드 내에서 지역 변수로 생성된 변수가 사용되지 않는 경우 에러를 발생시킨다. 단 전역으로 선언된 변수는 에러를 발생시키지 않는다.
// app.ts
let appId = 'abc' // 에러를 발생시키지 않음.
function clickHandler(message: string) {
let name = 'Lim' // 선언 후 사용하지않는다면 에러 발생
console.log('Clicked!' + message);
}
noUnusedParameters
noUnusedParameters
옵션은 선언된 매개변수가 사용되지 않는 경우 에러를 발생시킨다.
// app.ts
function clickHandler(message: string, age: number) {
// age 매개변수가 사용되지 않아 에러 발생
console.log('Clicked!' + message);
}
noImplicitReturns
noImplicitReturns
옵션 사용시 아래와 같이 반환하지 않을 수 있는 함수 사용시 에러가 발생한다.
function add(n1: number, n2: number){
if(n1 + n2 > 0){
return n1 + n2;
}
}
Visual Code 로 디버깅하기.
마켓플레이스에서 아래와 같은 확장 프로그램을 사용하는것을 추천한다.
ESLint
코드 품질 향상.Prettier
코드 형식 정돈.JavaScript Debugger
VS에서도 크롬의 개발자도구와 같이 디버깅이 가능하다.
- 단
sourceMap
옵션을true
로 지정한 상태여야만한다. 이후에는ts
코드에 종단점을 지정해주면 된다. 컴파일 이후 Run > Start Debugging 을 실행하면 아래와 같이 화면이 바뀐다.
VARIABLES
는 종단점 기준으로 변수를 추적한다.WATCH
는 현재 종단점의 변수 값의 변경이 가능하다. message + "!!!"를 입력해 You're welcome!!!! 와 같이 변수의 값을 변경할 수 있다.CALL STACK
은 호출된 함수 목록을 확인할 수 있다.