TypeScript에 대한 간단한 정리 - 01. 빠른 개발 환경 구성

2024. 12. 14. 18:54Programming Language/Node.js

01. 빠른 개발 환경 구성

타입스크립트는 자바스크립트에 추가적인 내용이 들어간거라고 생각하면 된다.

타입스크립트는 자바스크립트의 기능을 확장하여 정적 타입 검사(static type checking)를 제공하는 프로그래밍 언어이다.

타입스크립트는 자바스크립트의 문법을 그대로 따르지만, 타입 시스템을 추가하여 코드의 안정성을 높이고, 큰 프로젝트에서 발생할 수 있는 오류를 미리 방지하는 데 도움을 준다.

 

여기서 정적 타입 검사란 기존에 자바스크립트와는 다르게 타입스크립트는 변수, 함수 등의 타입을 명시할 수 있어, 코드 작성 중에 타입 오류를 미리 파악하고 수정할 수있게 되는 것을 말한다.

 

자바스크립트의 경우에는 런타임, 동작하는 환경에서 동작할때 오류를 확인하기 때문에 동작 환경에서만 타입 오류를 발견할 수 있다.

타입 스크립트는 코드를 작성할때 타입오류를 확인하기 때문에 작성할때 문제를 확인하고 수정할 수 있다.

그런데 브라우저나 node.js의 환경은 타입스크립트가 직접적으로 동작하지는 못한다.

타입스크립트는 자바스크립트의 슈퍼셋으로, 타입 시스템을 추가한 언어이기 때문에, 타입스크립트 코드타입스크립트 컴파일러(tsc)를 사용하여 자바스크립트로 변환한 후 실행할 수 있습니다.

그리고 이렇게 자바스크립트로 변환하는 과정을 컴파일이라고 부른다.

더보기

자바스크립트의 슈퍼셋이라는 말은 자바스크립트보다 더 큰 범위라는 의미이다.

쉽게 말하면, 슈퍼셋(Superset)은 기존 언어의 기능을 포함하면서, 추가적인 기능을 더한 언어이다. 즉, 타입스크립트(TypeScript)는 자바스크립트의 모든 기능을 그대로 가지면서 그 위에 새로운 기능을 더한 언어라는 뜻이다.

그래서 타입스크립트를 정적타입의 컴파일 언어라고 부른다.

 

이제 타입스크립트를 실행할 환경을 구성해보도록 하자.

먼저 VSCode를 사용해서 폴더 하나를 생성한 후 열어보자

그리고 터미널을 열어주고 package.json을 생성해주자.

그리고 parcel이란 패키지와 typescript패키지 두개를 설치해줄 것인데, parcel은 웹 애플리케이션 번들러로, 타입스크립트 파일을 자동으로 처리할 수 있게 도와주는 패키지이다.

이 두 패키지는 개발할때만 사용되고 실제 배포시에는 같이 배포되지 않게 개발 의존성(devDependencies)이라는 특별한 옵션을 추가해서 설치해야한다.

해당 옵션은 -D 혹은 --save-dev를 추가해서 설치해주면 된다.

 

npm install --save-dev parcel typescript

더보기

이거 설치할때 경로에 한글로 된 디렉터리가 있으면 설치 안되니까 디렉터리 명은 모두 영어로 수정할것..

이렇게 잘 디펜던시가 잘 설정된것을 볼 수 있다.

이제 스크립트를 생성해보자. 

parcel을 통해서 타입스크립트를 실행시키고 빌드할 것이기 때문에 실행시키는 명령어인 

"start": "parcel ./index.html",

를 추가해주고

빌드하는 명령어인 

"build": "parcel build ./index.html"

를 스크립트 안에 추가해주자.

더보기

 

  • start: parcel ./index.html 명령은 Parcel 개발 서버를 실행한다. index.html 파일을 기반으로 TypeScript 파일을 처리하고, 번들링하여 브라우저에서 실시간으로 결과를 확인할 수 있다.
  • build: parcel build ./index.html 명령은 배포용 빌드를 생성한다. 이 명령은 최적화된 번들 파일을 생성하며, 브라우저에서 사용할 수 있는 JavaScript 파일로 변환된다.

 

그리고 main이라는 필드는 진입점을 설정하는 것인데 이게 오류를 발생시킬 수 있기 때문에 지워주자.

이렇게 설정된 package.json은 

이렇게 구성된다.

 

이제 프로젝트의 루트경로에 index.html을 하나 생성해주자.

그리고 이 index.html에 타입스크립트 파일을 하나 연결해주려고 한다.

루트 경로에 src디렉터리를 하나 생성해주는데 이 src디렉터리는 보통 개발을 할때 필요한 다양한 소스 파일들을 넣어두는 디렉토리의 통상적인 명칭이라고 보면된다.

이 안에 main이라는 폴더를 만들어 줄건데 js파일이 아니라 타입스크립트인 ts를 확장자로 사용해서 생성해주자.

그리고 모듈을 연결하듯이 index.html에 해당 스크립트를 연결해주면 되는데, title 태그 아래에 script 태그를 하나 생성하고 

타입속성을 module로 설정해주자.

<script> 태그의 type="module"은 해당 JavaScript 파일이 ESM (ECMAScript Module) 형식임을 나타낸다. 즉, 모듈 방식으로 코드를 작성한다는 의미다. 모듈 방식에서는 import와 export를 사용할 수 있다. 예를 들어, module.js라는 파일에서 다른 파일을 가져오고 싶으면 이렇게 작성한다.

import { myFunction } from './myModule.js';

 

그리고 defer 속성을 추가해주고

defer 속성은 스크립트 파일이 HTML 문서가 파싱된 후에 실행되도록 한다. 즉, HTML 파일이 로드되는 동안 스크립트가 비동기적으로 다운로드되고, HTML 문서 파싱이 끝난 후에 실행된다. 이를 통해 HTML의 렌더링을 차단하지 않고, 페이지 로딩 성능을 개선할 수 있다

 

그리고 src 속성을 통해서 src폴더 내부에 main.ts파일을 연결해서 사용하겠다고 등록해주자.

브라우저가 TypeScript 파일을 이해할 수 없는데도 불구하고 src로 직접 지정할 수 있는 이유는 Parcel이 내부적으로 TypeScript 파일을 읽고 변환해서 브라우저가 이해할 수 있도록 만들어주기 때문에 가능한 것이다.

더보기

사실 여기서 defer의 구체적인 사용 용도가 성능향상때문인지 아닌지도 잘 모르겠지만...저 속성은 잘모르겠음;

이렇게 html에 타입스크립트도 연결 한 후에 추가로 만들어야 할 파일이 있는데 루트 경로에 tsconfig.json이란 파일을 하나 생성해주자.

 

tsconfig.json은 TypeScript 프로젝트의 설정 파일로, TypeScript 컴파일러(tsc)가 어떻게 코드를 변환할지에 대한 다양한 옵션을 지정하는 데 사용된다.

이 파일은 TypeScript 프로젝트에서 매우 중요한 역할을 하며, 프로젝트의 컴파일 규칙환경 설정을 정의한다.

복잡한 컴파일러 옵션을 커맨드라인에서 일일이 입력하지 않고, 설정 파일에 명시적으로 정의가 가능하다.

 

tsconfig.json은 JSON 형식으로 작성되며, 주요 키와 값은

{
  "compilerOptions": {
    "target": "ES6",
    "module": "CommonJS",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "**/*.test.ts"]
}

 

주요 옵션과 설명

compilerOptions

  • 컴파일러 동작을 제어하는 다양한 옵션을 지정하는 핵심 속성
옵션 설명 예시
target 변환 후의 JavaScript 버전을 설정 "ES5", "ES6"
module JavaScript 모듈 시스템을 지정 "CommonJS", "ESNext"
strict 엄격한 타입 검사 활성화 (권장). true
outDir 컴파일된 파일의 출력 디렉터리. "./dist"
rootDir TypeScript 소스 파일의 루트 디렉터리. "./src"
esModuleInterop ES 모듈과 CommonJS 모듈 간의 호환성을 보장. true
sourceMap 디버깅을 위한 소스맵 파일 생성 여부. true

**외에도 매우 많은 속성이 존재함

 

② include

  • 컴파일 대상 파일을 지정
  • 예: ["src/**/*"]
    → src 폴더의 모든 하위 폴더와 파일을 포함

③ exclude

  • 컴파일에서 제외할 파일을 지정
  • 예: ["node_modules", "**/*.test.ts"]
    → node_modules 폴더와 테스트 파일 제외

사용의 예를 보면 

{
  "compilerOptions": {
    "target": "ES6",        // ES6버전으로 변환되기를 원함
    "module": "CommonJS",   // CommonJS 모듈 시스템으로 구성되기를 원함
    "strict": true,         // 엄격한 타입검사를 원함
    "outDir": "./build",    // ./build에 컴파일한 파일이 생성되기를 원함
    "rootDir": "./src"      // 타입스크립트는 ./src폴더에 위치함
  },
  "include": ["src/**/*"]   // src아래에 있는 모든 파일을 타겟으로 함
}

 

해당 파일은 그냥 직접 생성해줄 수 도 있으나 

npx tsc --init

라는 명령어를 통해서도 생성할 수 있다.

(typescript가 전역으로 설치되어 있으면 그냥 tsc --init 해도 됨, 근데 로컬로 설치되어 있는 경우는 위와 같이 해주자)

 

** npx tsc --init을 해서 생성되는 tsconfig.json에는 대략적으로 들어올 수 있는 설정들에 대한 내용이 작성되어 있으니 참고하자.

 

아무튼 우리는 여기에

이렇게 작성할 것인데 하나 하나에 대한 설명을 해보자면 

 

1. target: "ES2015"

TypeScript가 코드를 컴파일할 때 변환할 JavaScript 버전을 ES2015로 지정한다

 

2. module: "ESNext"

JavaScript 모듈 시스템을 설정하는 것으로 ESNext는 최신 ES 모듈 형식을 사용하도록 지정한다

 

3. moduleResolution: "Node"

TypeScript가 모듈을 해석할 때 Node.js의 모듈 해석 방식을 따른다

 

4. esModuleInterop: true

ES 모듈(import/export)과 CommonJS 모듈(require/module.exports) 간의 호환성을 활성화한다

(ES 모듈 방식과 CommonJS 모듈 방식을 모두 인식하게 하겠다는 설정, 정확하게는 CommonJS 모듈(예: require)을 ES 모듈 방식(import)으로 더 쉽게 가져올 수 있도록 도와준다. TypeScript에서 CommonJS 모듈을 다룰 때 불편함이 존재하는데 이를 해소시켜준다.)

더보기

타입스크립트에서 CommonJS 모듈을 가져올 때는 * as 문법을 사용해야 한다.

// CommonJS 모듈 (예: lodash)
const lodash = require('lodash'); // CommonJS 스타일

// TypeScript에서 ES 모듈 방식으로 가져오기
import * as lodash from 'lodash'; // 이렇게 작성해야 함 (번거롭고 불편)

 

활성화되면 

// ES 모듈처럼 CommonJS 모듈을 가져오기
import lodash from 'lodash'; // 더 간결하고 읽기 쉬움

이렇게 쉽게 가져올 수 있게 된다

** Node.js 환경에서는 esModuleInterop을 활성화하는 것이 대부분 권장한다고 한다.

 

5. lib: ["ESNext", "DOM"]

TypeScript가 사용할 내장 라이브러리 타입 정의를 지정하는데 프로젝트에서 사용할 JavaScript API를 정의하는 데 사용된다.

 

  • ESNext: 최신 JavaScript 표준 기능(예: Promise.allSettled)을 포함
  • DOM: 브라우저 환경에서 사용할 수 있는 API (예: document, window 등)를 포함

**해당 옵션을 넣어주지 않으면 Promise나 window같은 함수 혹은 타입의 사용이 정의되지 않았다고 인식한다.

 

6. strict: true

TypeScript의 모든 엄격한 타입 검사 옵션을 활성화한다

 

이제 타입스크립트 코드를 작성하기 위한 준비가 끝났다.

이제 타입스크립트 코드를 조금 작성해서 문제가 없는지를 파악해보자.

 

main.ts파일에 변수하나를 let으로 생성해주고 숫자를 한번 할당해보자.

 

이건 기존의 자바스크립트와 동일하게 변수를 생성하는 과정이다.

여기에 변수명 뒤에 :을 붙인 후에 string이라고 작성해주면 

이렇게 string 타입의 변수에 number를 대입할 수 없다고 나오는데 이게 타입스크립트에서는 자바스크립트와 다르게 타입을 지정해주는 방법이다.

string, 문자열을 넣어야 하기 때문에 값을 

이렇게 문자열을 넣어줘야만 한다.

이 문자열을 console을 통해서 출력해보기로 하고 

이렇게 작성을 해주자.

 

그런데 이 타입스크립트는 브라우저에서 동작할 수 없기 때문에 자바스크립트로 변환을 해줘야 하는데 이때 사용하는게 parcel이라는 패키지이다.

 

먼저 우리가 스크립트에 start로 parcel ./index.html라는 스크립트를 등록했었기에 npm start를 통해서 해당 명령어를 사용해주면 

이렇게 타입스크립트를 사용하는 서버를 1234포트, 로컬호스트로 열어준 것을 볼 수 있다.

이렇게 parcel을 실행시켜주면 dist라는 폴더가 생성되고 

그 내부에 

js와 index.html이 존재하는데 index.html을 보면 

src 경로가 ts가 아니가 js파일을 바라보고 있음을 알 수 있다.

해당 자바스크립트 파일을 열어보면

알수 없는 엄청 많은 내용들이 존재하는데 여기서 우리가 작성한 변수 testVal과 console.log부분을 찾아보면 

이렇게 우리가 작성한 코드들이 존재한다.

그리고 잘 보면 우리가 타입스크립트로 타입을 설정했던 부분이 사라져있는 것을 볼 수 있다.

자바스크립트로 동작이 될때는 이런 타입스크립트에 맞게 설정된 부분들이 다 자바스크립트 형태로 변경되는 것을 알 수 있다.

그리고 브라우저에 localhost:1234로 접근해보면

이렇게 콘솔을 잘 찍는것을 볼 수 있다.

그리고 잘 보면 main.js가 아니라 main.ts로 되어 있는건 parcel 번들러에서 출력해주는 내용이기 때문이라서 그렇다고 한다(크게 중요하진 않은가봄)