티스토리 뷰
📝 이 포스팅은 인프런강의의 Zerocho의 Node.js에 TypeScript 적용 강의를 듣고 정리한 글입니다.
[vscode 환경세팅]
먼저 node 프로젝트 생성하고 package.json 이 초기에 세팅된 후에 vscode 환경세팅을 진행해주시면 됩니다.
Breadcrumbs 활성화 시키기
Breadcrumbs 는 typescript 파일의 위치를 파악할 수 있는 네비게이션 역할을 합니다.
⌘(cmd) + , 단축키는 vscode 설정(preferences) 로 이동합니다.
검색어에 bread 라고 입력하면 아래사진의 핑크색박스 처럼 비활성화된 상태로 나옵니다.
샐랙트박스를 체크합니다.
설치패키지
$ npm i prettier
$ npm i tslint
$ npm i tslint-config-prettier
package.json 에 "prettier" 키 값 추가합니다.
// package.json
{
... ,
"prettier": {
"printWidth": 80,
"useTabs": false,
"tabWidth": 2,
"bracketSpacing": true,
"semi": true,
"singleQuote": false
}
}
현재 프로젝트의 루트디렉토리에서 .vscode 폴더를 생성합니다.
.vscode 폴더안에 settings.json 파일을 생성합니다.
/ (루트디렉토리 = 최상단 디렉토리)
ㄴ .vscode
| ㄴ settings.json
ㄴ tslint.json
// settings.json
{
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.formatOnSave": false,
"prettier.tslintIntegration": true,
"tslint.autoFixOnSave": true
}
* "editor.formatOnSave": false 로 설정한 이유는 내장 lint 와 tslint 사이에 충돌 발생을 막기 때문입니다.
* "prettier.tslintIntegration": true 는 prettier가 prettier-tslint를 사용하여, tslint의 룰을 우선시함을 의미합니다.
루트 디렉토리에 tslint.json 파일 생성합니다.
tslint.json에 타입스크립트 작업할 때의 룰을 추가할 수 있습니다.
// tslint.json
{
"defaultSeverity": "error",
"extends": ["tslint:latest", "tslint-config-prettier"],
"jsRules": {},
"rules":{
"semicolon":true,
"import-spacing": true,
"whitespace": true
},
"trailing-comma": [
true,
{
"multiline": {
"arrays": "always",
"exports": "always",
"functions": "always",
"imports": "always",
"objects": "always",
"typeLiterals": "always"
},
"singleline":{
"arrays": "always",
"exports": "always",
"functions": "never",
"imports": "always",
"objects": "always",
"typeLiterals": "always"
},
"esSpecCompliant": true
}
],
"space-before-function-paren": [
true,
"never"
],
"extends": ["tslint:recommended", "tslint-config-prettier"]
}
[참고 - vscode에 typescript 환경 설정]
[TypeScript] TS 환경 설정 Visual Studio Code (TypeScript Configuration in Visual Studio Code)
우선 TypeScript 백문이 불 여일 타 라고 docs가 너무 잘되어있는 사이트가 있어서 한번 다 입력하면서 이것저것 내용들을 작성해볼까 합니다. 기존에 바닐라 JS도 TS로 이어서.. 진행하려고 합니다.
ipex.tistory.com
VScode 에서 Typescript 환경 설정하기
typescript설치에서 TSlint, prettier 까지
medium.com
[typescript] vscode에서 typescript 프로젝트에 tslint 적용
e이전 포스팅인 vscode에서 typescript 프로젝트 생성에서 생성한 프로젝트 기준으로 설명한다 vscode에서 typescript 프로젝트 생성 tslint를 사용하기 위해선 tslint, tslint-config-standard 두가지 모듈이 필..
choiyb2.tistory.com
- 필자는 npm package manager을 이용했습니다!
- node.js 를 이미 설치되어야 합니다. 필자는 LTS 버젼으로 설치했습니다.
node.js/express 프로젝트에 Typescript 연결 작업
package.json 생성하여 노드프로젝트 생성
$ npm init --y
node.js+typescript 에서 필요한 패키지들
1. 패키지 라이브러리 설치
package.json의 dependency 영역에 설치
> typescript 설치
$ npm i typescript
> @types/node 설치
$ npm i @types/node
> express 와 @types/express 설치
$ npm i express @types/express
> morgan, cors, cookie-parser, express-session, dotenv, passport, hpp, helmet 설치
$ npm i morgan cors cookie-parser express-session dotenv passport hpp helmet
> @types/morgan, cors, cookie-parser, express-session, dotenv, passport, hpp, helmet 설치
$ npm i @types/morgan @types/cors @types/cookie-parser @types/express-session @types/dotenv @types/passport @types/hpp @types/helmet
2. 개발자용 패키지 라이브러리 설치
package.json의 devDependency 영역에 설치
> nodemon 설치
$ npm i -D nodemon
> ts-node 설치
$ npm i -D ts-node
tsconfig.json 생성
[+] tsconfig.json 이 무엇인가요?
tsconfig.json 이 위치한 디렉토리가 Typescript 프로젝트의 루트(최상단)이 됩니다.
tsconfig.json은 프로젝트를 컴파일하는데 필요한 루트파일과 컴파일 옵션을 지정합니다.
입력파일 없이 tsc를 호출하면, 컴파일러는 현재 디렉토리에서부터 시작하여 상위디렉토리 체인으로 tsconfig.json 파일을 검색합니다.
[ tsconfig.json 에 대한 참고 자료 ]
프로젝트의 루트디렉토리에 tsconfig.json 을 생성합니다.
{
"compilerOptions": {
"strict": true,
"lib": [
"es2015",
"es2016",
"es2017",
"es2018",
"es2019",
"es2020",
"es2021"
],
"moduleResolution": "node",
"esModuleInterop": false,
"typeRoots": ["./types"],
"sourceMap": true
}
}
- strict : typescript 코드 문법 규칙을 엄격하게 검사합니다. warning이어도 에러로 인식합니다.
- moduleResolution : 컴파일러가 "import가 무엇을 참조하는지"를 알아내기 위해 사용하는 프로세스입니다.
import { a } from "moduleA" 의 예를 들면, a를 검사하기 위해 컴파일러는 무엇을 참조하는지 정확히 알아야됩니다.
그러므로 컴파일러는 moduleA 정의를 검사해야 됩니다.
컴파일러가 모듈 moduleA를 해석할 수 없다면, 오류로그 error TS2307: Cannot find module 'moduleA' 를 발생합니다.
moduleA는 .ts/.tsx 파일에 정의되어 있거나, 코드가 의존하는 *.d.ts에 정의되어 있을 수 있습니다.
컴파일러는 두가지 전략 으로 가져온 모듈을 나타내는 파일의 위치를 찾습니다. 두가지 전략은 'Node' 와 'Classic' 입니다.
moduleResolution - Classic 전략
Classic 전략은 Typescript의 default 해석전략이며, 이전 버젼과의 호환성을 위해 제공됩니다.
// path: /root/src/folder/A.ts
// file-name: A.ts
import { b } from "./moduleB";
위와 같이 A.ts 안에 moduleB의 b를 임포트 했다면 모듈 moduleB 가 무엇인지를 검사합니다.
먼저 A.ts 와 같은 위치에 있고, 확장자가 moduleB.ts 인지, moduleB.d.ts 인지를 확인합니다.
(검사1)
moduleB의 디렉토리가 /root/src/folder/moduleB.ts 인가? /root/src/folder/moduleB.d.ts 인가?
A.ts 의 현재 디렉토리에 위치하지 않는다면, moduleB 파일의 위치를 찾기위해서 디렉토리 트리를 거슬러 올라가서 위치를 찾습니다.
(검사2)
/root/src/folder/ 디렉토리에 moduleB.ts 나 moduleB.d.ts(정의파일)이 있는가?
/root/src/ 디렉토리에 moduleB.ts 나 moduleB.d.ts 가 있는가?
/root/ 디렉토리에 moduleB.ts 나 moduleB.d.ts 가 있는가?
/ 디렉토리에 moduleB.ts 나 moduleB.d.ts 가 있는가?
moduleResolution - Node 전략
Node 전략은 런타임에 Node.js 모듈 해석 메커니즘으로 파일의 위치를 찾습니다.
commonJS 방식을 사용합니다.
[Node 방식]
TypeScript 한글 문서
TypeScript 한글 번역 문서입니다
typescript-kr.github.io
import * as express from 'express' vs import express from 'express'
* as 가 없으면 export default 로 정의되어 있습니다.
* as 가 붙어있는 것은 export default 로 정의 되어있지 않음을 의미합니다.
typescript 파일에서 express 모듈을 불러오는 것은
node_modules/@types/express/index.d.ts 파일을 가리킵니다.
여기서 express 모듈이 어떻게 정의되어있는지 아래 코드를 확인해보면
export default express; 이런식으로 정의되어 있지 않았습니다.
node_modules/@types/express/index.d.ts 소스코드 보기
// path: node_modules/@types/express/index.d.ts
// Type definitions for Express 4.17
// Project: http://expressjs.com
// Definitions by: Boris Yankov <https://github.com/borisyankov>
// China Medical University Hospital <https://github.com/CMUH>
// Puneet Arora <https://github.com/puneetar>
// Dylan Frankland <https://github.com/dfrankland>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/* =================== USAGE ===================
import express = require("express");
var app = express();
=============================================== */
/// <reference types="express-serve-static-core" />
/// <reference types="serve-static" />
import * as bodyParser from 'body-parser';
import * as serveStatic from 'serve-static';
import * as core from 'express-serve-static-core';
import * as qs from 'qs';
/**
* Creates an Express application. The express() function is a top-level function exported by the express module.
*/
declare function e(): core.Express;
declare namespace e {
/**
* This is a built-in middleware function in Express. It parses incoming requests with JSON payloads and is based on body-parser.
* @since 4.16.0
*/
var json: typeof bodyParser.json;
/**
* This is a built-in middleware function in Express. It parses incoming requests with Buffer payloads and is based on body-parser.
* @since 4.17.0
*/
var raw: typeof bodyParser.raw;
/**
* This is a built-in middleware function in Express. It parses incoming requests with text payloads and is based on body-parser.
* @since 4.17.0
*/
var text: typeof bodyParser.text;
/**
* These are the exposed prototypes.
*/
var application: Application;
var request: Request;
var response: Response;
/**
* This is a built-in middleware function in Express. It serves static files and is based on serve-static.
*/
var static: serveStatic.RequestHandlerConstructor<Response>;
/**
* This is a built-in middleware function in Express. It parses incoming requests with urlencoded payloads and is based on body-parser.
* @since 4.16.0
*/
var urlencoded: typeof bodyParser.urlencoded;
/**
* This is a built-in middleware function in Express. It parses incoming request query parameters.
*/
export function query(options: qs.IParseOptions | typeof qs.parse): Handler;
export function Router(options?: RouterOptions): core.Router;
interface RouterOptions {
/**
* Enable case sensitivity.
*/
caseSensitive?: boolean | undefined;
/**
* Preserve the req.params values from the parent router.
* If the parent and the child have conflicting param names, the child’s value take precedence.
*
* @default false
* @since 4.5.0
*/
mergeParams?: boolean | undefined;
/**
* Enable strict routing.
*/
strict?: boolean | undefined;
}
interface Application extends core.Application {}
interface CookieOptions extends core.CookieOptions {}
interface Errback extends core.Errback {}
interface ErrorRequestHandler<
P = core.ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = core.Query,
Locals extends Record<string, any> = Record<string, any>
> extends core.ErrorRequestHandler<P, ResBody, ReqBody, ReqQuery, Locals> {}
interface Express extends core.Express {}
interface Handler extends core.Handler {}
interface IRoute extends core.IRoute {}
interface IRouter extends core.IRouter {}
interface IRouterHandler<T> extends core.IRouterHandler<T> {}
interface IRouterMatcher<T> extends core.IRouterMatcher<T> {}
interface MediaType extends core.MediaType {}
interface NextFunction extends core.NextFunction {}
interface Request<
P = core.ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = core.Query,
Locals extends Record<string, any> = Record<string, any>
> extends core.Request<P, ResBody, ReqBody, ReqQuery, Locals> {}
interface RequestHandler<
P = core.ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = core.Query,
Locals extends Record<string, any> = Record<string, any>
> extends core.RequestHandler<P, ResBody, ReqBody, ReqQuery, Locals> {}
interface RequestParamHandler extends core.RequestParamHandler {}
export interface Response<ResBody = any, Locals extends Record<string, any> = Record<string, any>>
extends core.Response<ResBody, Locals> {}
interface Router extends core.Router {}
interface Send extends core.Send {}
}
export = e;
export default 로 정의되지 않았으므로, @types/express 모듈을 불러올 때
import * as express from "express" 로 정의해야합니다.
ts-node
ts-node 는 Typescript 실행 엔진 이며, Node.js 의 REPL 입니다.
REPL이란, Read Evaluate Print Loop 의 줄임말이며
직역하면, 사용자가 특정 코드를 입력하면 해당코드를 평가, 실행결과를 반환, 출력, 반복해주는 환경을 의미합니다.
Node.js에서의 자바스크립트 코드를 즉석으로 바로 실행해서 결과를 확인해볼 수 있음을 의미합니다.
ts-node는 typescript 를 javascript 로 변환시킵니다.
또한 다른 Node.js 툴과 라이브러리를 함께 사용할 수 있도록 합니다.
사전 컴파일(pre-compiling) 없이 Node.js에서도 Typescript로 직접 실행시킬 수 있도록 합니다.
$ npx ts-node index.ts
* npm이 아닌 npx 로 한 이유는, 글로벌 설치를 막기 위해서 입니다.
위의 코드의 실행결과는, index.js 를 생성시킵니다.
ts-node가 node.js 환경에서 동작할 수 있도록 typescript를 javascript 로 변환시킵니다.
npm 과 npx 의 차이점이 무엇일까요?
npm은 로컬에 모듈을 설치를 해야 동작이 됩니다.
반면에, npx는 로컬에 모듈을 설치하지 않아도 최신버젼을 바로 실행시켜 버젼에 구애받지 않습니다.
npm은 패키지를 관리만 하고 실행을 할 수 없습니다. 반면에, npx는 npm 패키지 실행기 이므로 npm을 실행 시킬 수 있습니다.
npm 의 글로벌 모듈(-g)의 도입 목적은, 매 프로젝트마다 모듈 설치를 하지 않기 위해서 였습니다.
매번 모듈설치를 하는 귀찮음을 해결할 수 있습니다. npm으로 글로벌 모듈 설치하는 명령어는 아래와 같습니다.
$ npm i 모듈명 -g
하지만 글로벌로 모듈을 설치하는게 마냥 좋은 방법은 아닙니다. 대표적으로 글로벌 모듈이 좋지 않은 이유는 세가지 입니다.
1) 모듈이 업데이트 되어있는지 확인이 어렵다.
2) 업데이트 진행했을 때 변동사항이 생겨 다른 프로젝트에도 영향을 끼칠 수 있다.
3) create-react-app 같은 보일러 플레이트에는 치명적이다.
npm 5.2 버젼부터 npx를 기본패키지로 제공되기 시작했습니다. npx도 모듈의 일종입니다.
npx는 특히 3번째 문제인 create-react-app 보일러플레이트 모듈의 문제점을 해결해줬는데
create-react-app 을 설치할 경우 매번 최신버젼만을 가져와서 설치해주기 때문에
지금 어떤 버젼을 사용하고 있는지 신경쓸 필요가 없어졌습니다.
npm을 통해 모듈을 로컬에 설치해야 실행시킬 수 있다는 문제점을 보완해줬습니다.
npx는 모듈을 로컬에 저장하지 않고 매번 최신 버젼의 파일만을 임시로 불러와 실행시킵니다.
[참고자료]
ts-node
Overview | ts-node
ts-node is a TypeScript execution engine and REPL for Node.js.
typestrong.org
npx 와 npm 차이
npm과 npx의 차이에 대해서 - React
리액트 프로젝트 생성 도구인 create-react-app 같은 모듈의 경우, 변경사항이 꽤나 잦은 모듈입니다. 그렇기 때문에 매 설치 전마다 npm으로 재 설치를 하지 않는 경우에는 이전 버전을 사용할 여지
ljh86029926.gitbook.io
npm 과 npx 차이 - 하나몬
❗️npm과 npx 차이 (npm 놔두고 yarn 패키지 매니저 사용 이유까지) 👉 npm의 본질은 node.js 모듈이다. 터미널을 열어서 다음 명령어를 통해 글로벌로 설치된 node.js 모듈을 확인할 수 있다. cd /usr/local/
hanamon.kr
'Backend > 꾸준히 TIL' 카테고리의 다른 글
[IT용어] IT관련 "개발용어"에 익숙해지자 4편 - "확장성" 있는 코드? (2) | 2022.10.04 |
---|---|
[Javascript] callback함수와 async와 await 그리고 Promise 에 대한 이해 (0) | 2022.10.03 |
zsh 환경에서 ruby 패키지매니저 gem 설치하기 (0) | 2022.09.26 |
[node.js] 3Layers Architecture 로 리팩토링하기 (2) | 2022.09.20 |
IT관련 "개발용어"에 익숙해지자 3편 - library 와 framework (0) | 2022.09.15 |
- Total
- Today
- Yesterday
- RDBMS
- MongoDB
- 습관개선
- 바이트디그리
- MySQL
- nestjs jest
- OS
- 미완
- typeORM
- gem
- IT용어
- node.js
- 갓생살자
- Nest.js
- vscode
- jest
- Jekyll
- 개발용어
- 나도 할 수 있다
- 참고
- 한달독서
- Mongoose
- 디지털디톡스
- 스마트폰중독
- 클린아키텍쳐
- TDD
- git
- 한달어스
- nestjs
- TypeScript
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |