타입스크립트 프로젝트 설정

타입스크립트 프로젝트 옵션 설정하기

Intro


타입스크립트 컴파일러

  • 보다 큰 프로젝트를 사용하기 위해 편의성 개선을 위한 컴파일러 설정하기

시계 모드 사용


현재 개발 환경에서 변경사항이 있는 경우 이를 자바스크립트로 컴파일해 런타임 환경에서 작동하도록 아래와 같은 명령을 수동으로 입력하고 있다.

bash
tsc app.ts

위 과정을 파일이 변경될 때마다 컴파일되도록 반영하고 싶다면 관찰모드를 이용한다. 아래 명령을 입력하면 해당 파일에 변경사항이 있는 경우 컴파일이 진행된다.

bash
tsc app.ts -w

다수의 파일 자동 컴파일하기


아래와 같이 html 파일에서 다수의 스크립트를 사용하는 경우 다수의 파일을 컴파일할 수 있도록 해보자.

html
<script src="app.js" defer></script>
<script src="app2.js" defer></script>

아래와 같이 파일명을 지정하지 않은채 컴파일 명령을 입력한다.

bash
tsc

혹은 프로젝트를 타입스크립트 프로젝트로 지정한다. 이 커맨드가 실행되는 폴더의 모든 파일을 인식하게 된다.

bash
tsc --init

이후 프로젝트내 tsconfig.json 파일이 생성된다. 이 파일은 타입스크립트가 관리해야할 파일이 포함된 프로젝트, 모든 하위 폴더를 참고하기 위한 파일이다.
이후에 컴파일 명령 혹은 관찰 모드 커맨드를 입력하면 프로젝트내 모든 .ts 파일을 감지해 변경사항이 있는 경우 컴파일을 진행한다.

tsconfig 설정하기


프로젝트내 생성된 tsconfig.json 파일은 프로젝트내 파일 제외/추가 혹은 컴파일 대상을 설정하는 타입스크립트 설정 파일이다.

파일 포함 및 제외하기


exclude


tsconfig.json를 열고 exclude옵션을 이용할 수 있다. 와일드 카드(_)를 이용할 수 있는데 , _.dev.ts라는 확장자로 exclude옵션에 포함시킨 경우 .dev.ts로 끝나는 모든 파일을 제외한다. 모든 폴더에서 적용할 경우\*_/_.dev.ts를 입력한다.

json
// tsconfig.json
"exclude": [
  "node_modules" // would be the default
]

기본적으로 라이브러리 폴더인 node_modules는 설정상 자동으로 제외된다.

include


json
// tsconfig.json
"include": [
  "app.ts"
]

만일 위와 같이 include 옵션에 app.ts만 정의한 경우 app.ts 변경사항이 발견된 경우에만 컴파일되며 다른 *.ts 파일을 컴파일되지 않는다.
필요한 파일만 지정해 컴파일할 수 있다. 이와 같이 excludeinclude를 함께 사용하면 include가 필터링된다.
기본적으로 exclude 옵션만 이용한다.

files


include와 다소 비슷한 files 옵션도 있는데, include는 제외하고자 하는 항목을 전체 폴더를 지정하지만 files는 컴파일하고자 하는 개별 파일만을 지정할 수 있다.

json
// tsconfig.json
"files": [
  "app.ts"
]

컴파일 대상 설정하기


compilerOptions옵션은 타입스크립트 코드가 컴파일되는 방식을 관리한다.

target


json
// tsconfig.json
"compilerOptions": {
  "target": "es5"
}

해당 옵션은 기본적으로 설정되어 있고 어떤 자바스크립트 버전으로 컴파일할 것인지 설정한다.
es5 의 경우 let, const가 포함되지 않으므로 컴파일 후 var로 대체될 것이다.
이와 같은 점으로 타입스크립트는 이전 브라우저에서도 작동하는 코드를 생성할 수 있다. target을 지정하지 않으면 타입스크립트는 번호가 없는 es만 컴파일하므로 이전 버전도 지원할 수 있다.

lib


lib옵션을 사용 이전에 이해할 사항이 있다. 아래와 같이 타입스크립트에서도 dom에 접근하여 이벤트를 생성할 수 있다.

ts
// app.ts
const button = document.querySelector('button')!;
// 타입스크립트는 런타임 상황에서 작동하지 않으므로. 위와 같은 dom이 존재하는지 확인할 수 없다. 
// ! 는 기본적으로 버튼 이라는 개체가 존재하니 값이 반환될 것이라고 타입스크립트에게 알려준다

button.addEventListener('click', () => {
  console.log('클릭!');
})

다시말하지만 타입스크립트는 컴파일 이후 자바스크립로 변경되어 브라우저에서 작동하게 된다. 즉 타입스크립트는 브라우저를 위해 작성하지 않는다.

위와 같이 작성 후 컴파일을 해보면 정상적으로 컴파일된것을 확인할 수 있다. 어떻게 타입스크립트가 document, const 변수가 존재하는것을 타입스크립트가 알 수 있을까?
또한 querySelector 메소드가 존재하는 객체를 포함하는것을 어떻게 알 수 있을까, 이는 lib 옵션때문이다.

json
// tsconfig.json
"compilerOptions": {
  // "lib": [],
}

lib 설정이 안 되어 있다면 기본 설정은 target 옵션에 의지한다. es6로 설정한 경우 es6에서 사용가능한 옵션이 전역으로 타입스크립트에 적용된다.
즉 dom과 같은 자바스크립트 API를 사용할 수 있다. 기본으로 lib옵션은 주석처리 되어 있다.

json
// tsconfig.json
"compilerOptions": {
  "lib": [
    "dom",
    "es6",
    "dom.iterable",
    "scripthost"
  ],
}

위와 같이 target 옵션에 의지하지 않고 선택적으로 API를 선택해 타입스크립트 프로젝트에 적용할 수 있다. 위 옵션 4가지는 주석 처리된 경우 target 옵션에 의지할 때 적용되는 API와 동일하다.

allow


allowJS옵션과 checkJS옵션은 주로 같이 사용되며 타입스크립트가 자바스크립트 파일을 컴파일할 수 있도록 도와준다.
.ts로 끝나지 않는 파일도 컴파일할 수 있게된다.

checkJS옵션을 사용하면 타입스크립트는 컴파일을 수행하지 않고 구문 검사를 진행하고 잠재적 에러를 보고한다. .ts파일에서 변환된 .js 파일에 대해 컴파일을 두 번 수행할 필요가 없으므로 기본적으로 주석처리되어있다.

보통 타입스크립트를 사용하지 않는 프로젝트 환경에서 사용한다.

json
// tsconfig.json
"compilerOptions": {
  "allowJs": true,
  "checkJs": true,
}

sourceMap


sourceMap옵션은 디버깅 작업과 개발에 유용하다.

json
// tsconfig.json
"compilerOptions": {
  "sourceMap": true
}

sourceMap옵션을 true로 설정한 후 컴파일하게되면 .js파일과 함께 js.map파일도 생성된다.

js
// 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폴더내 저장된다.

json
// tsconfig.json
"compilerOptions": {
  "outDir": "./dist"
}

컴파일 후dist폴더내 저장된다. 이때 폴더 경로또한 그대로 복사되어 생성된다.

image

rootDir


rootDir옵션으로 루트 디렉토리를 설정하여 컴파일이되는 경로를 설정할 수 있다. 아래의 rootDir옵션과 같이 설정한 경우 컴파일을 하되, src내 타입스크립트 파일만 dist폴더에 저장된다.

json
// tsconfig.json
"compilerOptions": {
  "rootDir": "./src"
}

다음과 같이 컴파일 후 src폴더내 존재하던 파일만 dist폴더에 저장된다.

image

removeComments


removeComments 옵션을 true로 설정한 경우 컴파일과정에서 소스 코드내 주석은 제외된채로 생성된다.

json
// tsconfig.json
"compilerOptions": {
  "removeComments": true
}

downlevelIteration


코드를 이전 버전의 자바스크립트로 컴파일하고 for 루프로 작업해 컴파일 과정에서 보다 정확하게 수행할 수 있다.

json
// tsconfig.json
"compilerOptions": {
  "downlevelIteration": true
}

컴파일 오류 시 파일(js) 생성 중단하기


기존 타입스크립트 파일은 컴파일시 에러 유무의 상관없이 js 파일로 생성되었다. 이렇게 생성된 js파일은 브라우저에서 런타임시 오류가 발생한다.

noEmitOnError

noEmitOnError옵션의 기본값은 false다. 즉 에러 유무의 상관없이 컴파일 후 js파일을 생성한다.
만일 true로 설정하는 경우 타입스크립트 소스 에러 발생 후 컴파일시 js파일이 생성되지 않는다.

json
// tsconfig.json
"compilerOptions": {
  "noEmitOnError": true
}

Strict 컴파일


strict옵션은 아래 주석 처리된 7가지 모든 strict 관련 옵션을 관리한다.
strict옵션을 true로 설정한 경우 모든 아래 7개의 strict검사 옵션을 모두 사용할 수 있다. 개별적으로 옵션을 설정할 경우 strict관련 옵션을 개별적으로 true 혹은 false설정하여 검사 옵션을 지정할 수 있다.

json
//tsconfig.josn
"compilerOptions": {
   "strict": true,
    // "noImplicitAny": true,
    // "strictNullChecks": true,
    // "strictFunctionTypes": true,
    // "strictBindCallApply": true,
    // "strictPropertyInitialization": true,
    // "noImplicitThis": true,
    // "alwaysStrict": true,
}

noImplicitAny


noImplicitAny는 더 나은 코드를 작성하는데 도움을 준다. noImplicitAny옵션을 true로 사용한 경우 컴파일시 함수의 매개변수 타입이 any 타입인 경우 에러를 발생시킨다. 함수 생성시점에서 해당 값으로 어떤 결과가 나타날지 추론할 수 없기 때문이다.

단 변수의 경우는 타입을 명시적으로 지정하지 않더라고 생성 시점의 타입을 추적하기 때문에 이러한 에러가 발생하지 않는다.

ts
// analytics.ts
let logged; // any 타입.

function sendAnalytics(data: string){
    // 함수의 매개변수 타입을 지정하지 않고 후에 함수 호출시 값을 저장하는 경우
    // 호출 시점 보다 함수가 생성되는 시점이 먼저 발생한다. 함수 생성 시점에는 어떤 결과가 나타날지 알 수 없다.
    // 때문에 함수의 경우 매개변수 타입을 명확히 지정해야한다.
    console.log(data);
    logged = true; // 단 변수의 경우 타입을 명시적으로 지정하지 않더라도 생성단계에서 any로 지정되어 에러가 발생하지 않는다.
}

sendAnalytics('The Data');

noImplicitAny옵션을 true로 설정한 경우에 함수의 매개변수 타입을 지정하지 않는다면 아래와 같이 에러를 발생시킨다. false로 설정한 경우 에러를 발생시키지 않는다.

strict 옵션만 true

strictNullChecks


strictNullChecks는 아래와 같은 dom과 같은 경우를 예로 들 수 있다. 만일 아래 코드와 같이 작성 후 컴파일 한다면 에러를 발생시킨다. 버튼의 유무를 확인할 수 없기 때문이다.
null값을 잠재적으로 가질 수 있는 값을 컴파일시 알려준다. 타입스크립트는 html 페이지를 알지 못하므로 존재 유무를 알 수 없다.

ts
// app.ts
const button = document.querySelector('button');

button.addEventListener('click', () =>{
    console.log('Clicked!');
})

strictNullChecks옵션을 false로 설정하면 아래와 같은 에러가 발생하지 않는다.

dom 에러

에러를 발생시키지 않도록 아래와 같이 코드를 수정할 수 있다.

ts
// app.ts
// [1] !로 해당 값은 잠재적 null을 가지지 않는다고 명시해주어야한다.
const button = document.querySelector('button')!; 

// [2] if 문으로 존재 유무를 파악한다.
if(button){
  button.addEventListener('click', () =>{
      console.log('Clicked!');
  })
}

strictBindCallApply


strictBindCallApply옵션은 호출 함수가bind,call,apply 중 무엇에 해당하는지 확인 후 함수에 적용되었는지 검사한다.
만일 아래와 같이 매개변수를 정확히 전달하지 않은 경우 에러가 발생한다. 실수를 방지해준다.

ts
// 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 모드를 사용한 자바스크립트 파일을 생성한다.

js
// 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옵션은 클래스 부분과 이어지므로 후에 설명한다.

코드 품질 옵션


잘못된 변수 사용에 대한 에러를 아래와 같은 옵션으로 검사한다. 선언되었지만 사용되지 않거나

json
//tsconfig.josn
"compilerOptions": {
 /* Additional Checks */
    // "noUnusedLocals": true,
    // "noUnusedParameters": true,
    // "noImplicitReturns": true,
    // "noFallthroughCasesInSwitch": true,
}

noUnusedLocals


noUnusedLocals 옵션은 코드 내에서 지역 변수로 생성된 변수가 사용되지 않는 경우 에러를 발생시킨다. 단 전역으로 선언된 변수는 에러를 발생시키지 않는다.

ts
// app.ts
let appId = 'abc' // 에러를 발생시키지 않음.

function clickHandler(message: string) {
  let name = 'Lim' // 선언 후 사용하지않는다면 에러 발생
  console.log('Clicked!' + message);
}

noUnusedParameters


noUnusedParameters 옵션은 선언된 매개변수가 사용되지 않는 경우 에러를 발생시킨다.

ts
// app.ts
function clickHandler(message: string, age: number) {
  // age 매개변수가 사용되지 않아 에러 발생
  console.log('Clicked!' + message);
}

noImplicitReturns


noImplicitReturns옵션 사용시 아래와 같이 반환하지 않을 수 있는 함수 사용시 에러가 발생한다.

ts
function add(n1: number, n2: number){
  if(n1 + n2 > 0){
    return n1 + n2;
  }
}

Visual Code 로 디버깅하기.


마켓플레이스에서 아래와 같은 확장 프로그램을 사용하는것을 추천한다.

  1. ESLint 코드 품질 향상.
  2. Prettier 코드 형식 정돈.
  3. JavaScript Debugger VS에서도 크롬의 개발자도구와 같이 디버깅이 가능하다.
  • sourceMap옵션을 true로 지정한 상태여야만한다. 이후에는 ts코드에 종단점을 지정해주면 된다. 컴파일 이후 Run > Start Debugging 을 실행하면 아래와 같이 화면이 바뀐다.

디버그 화면

  • VARIABLES는 종단점 기준으로 변수를 추적한다.
  • WATCH는 현재 종단점의 변수 값의 변경이 가능하다. message + "!!!"를 입력해 You're welcome!!!! 와 같이 변수의 값을 변경할 수 있다.
  • CALL STACK은 호출된 함수 목록을 확인할 수 있다.

추가 정보