작년 제2회 유니톤(대학생 연합 해커톤)에 나가면서, 절실히 느꼈던 것은 미리 준비해 갈 수 있는 것들에 대해서 준비하지 않아서 애를 많이 먹었다. 예를 들어 프로젝트의 boilerplate, 프로젝트 디렉토리 설정, linter설정, db connect, server config, aws설정을 미리 해갈 수 있었다면 좀 더 빨리 기능구현을 할 수 있지 않을까 생각했다.
Boilerplate는 변경 없이 재 사용할 수 있는 물품을 말한다. 이 용어는 철강쪽에서 유래된 단어로, 보일러 플레이트는 증기 보일러 내에 사용되는 커다란 압연 강판을 말한다. 이처럼, 오랜 기간동안 사용되었으며 튼튼하거나 반복적으로 재사용하기 충분한 정도로 만들어진 물품을 말한다.
소프트웨어에서는, 일종의 기본설정이 되어있고 디렉토리설정이 되어있는 재사용 가능한 템플릿 이라고 볼 수 있다.
가장 유명한 boilerplate는 아마도 HTML5 Boilerplate: The web’s most popular front-end template가 아닐까.
Node.js는 크롬 V8 Javascript Engine위에서 동작하는 Javascript runtime이고 이벤트-드리븐 방식, non-blocking I/O를 사용하므로 가볍고 효율적이다. node의 생태계중 하나인 NPM은 세계에서 가장 큰 오픈소스 생태계 중 하나이다.
무슨 소리인지 하나도 모르겠다. 라고 생각하는 독자가 있다면 단어 하나하나에 걸려있는 링크를 참조하며 이해하도록 하자. 개발자가 되려면 모르는 것을 검색하고 스스로 학습하는 습관을 들여야 한다.
Node에 대한 기본 지식이 없다면 간단히 Mooc에서 기본 개념정도는 알아두고 시작하는 것이 좋다고 생각한다. 추천하는 Mooc는 역시 codeschool의 Node.js Tutorial | Code School , Express.js Tutorial | Code School를 참조하는 것이 좋다. codeschool은 유료기는 하지만 충분이 가격 대비 품질이 보증되는 Mooc이므로 무조건 추천한다.
Typescript는 순수한 자바스크립트로 컴파일되는 자바스크립트 superset이다. 컴파일 타임에서 타입을 체크하는 언어이고, Microsoft가 주요 Maintainer이며 Angular , Ionic Framework , Aurelia, DoJo등 많은 오픈소스에서 이미 채택되어 사용중이다.
쉽게 말하면 타입이 있는 자바스크립트이다. 타입스크립트는 3가지 특징을 가지고있다.
MongoDB는 대표적인 NoSQL으로 알려져있다. Scheme에 제약된 조건이 없으며 row수가 많은 데이터를 보관, 검색이 간편하고 scale-out에 장점을 가지고 있는 DB로 알려져있다.
사실 필자도 사이드 프로젝트를 하면서 Codeschool 강의를 참조하고, CRUD정도 작성해 본 것이 전부이기 때문에 다음 포스팅에서 자세히 작성하겠다.
자 이제 기본 개념들을 알았으니 한번 사용해보자.
물론, 이 블로그 아티클을 보는 사람의 컴퓨터에 Node.js 환경이 구축되어 있다는 것을 가정한다. 만약 Node.js가 구축되지 않은 환경이라면 Node.js 설치 링크를 참조하고 난 후 진행한다. Node.js 환경이 구축되어 있다면 NPM이 설치되어 있을 것이다.
$ npm -v
4.0.5
$ npm install -g tslint typescript
TSLint 란 typescript 전용 linter이다. linter는 여러명이서 협업을 진행할때 코딩 스타일, 코딩 컨벤션을 지정해 주는 툴이고 보면 된다. 유명한 linter에 관한 짤은 다음 그림을 참조하자.
이 프로젝트에서 쓰지 않지만 typings와 tsd에 대해서 궁금한 사람들이 혹시 있을까봐 적는다.
typings란 기존 자바스크립트 라이브러리들의 타입 정보만을 선언한 파일을 내려받을 수 있도록 도와주는 tool이다. 그리고 typings 마저도 이제 안 쓴다.
사실 필자도 설치하는 방법, 설정들을 정리하면서 @types/package들과 typings둘의 차이점에 대해서 몹시 궁금해졌다. 아무거나 적당히 사용하면 되는게 아닌가? 했지만 블로그에 글을 실으려면 정확한 정보를 제공해야 하기 때문에 구글링을 해 보았다.
구글 검색어: typings vs @type (외국도 한국처럼 vs를 참 좋아한다. 2가지 비교하고 싶으면 compare보다 vs를 치는게 훨씬 잘 나오는듯)
역시나 갓버플로우 형님들이 깔끔한 답변을 넣어줬다.
TypeScript typings in NPM @types org packages - Stack Overflow
3줄요약
결론적으로는
$ npm install @types/express
로 라이브러리를 설치하고import * as express from "express”;
이렇게 사용한다.
필자는 Webstorm을 주로 사용하고, Webstorm에서 node project를 만들때는
Webstorm의 file탭-new탭-project를 클리하면 다음 화면이 나오고, 원하는 generator 버전, template 엔진을 선택한다.
Webstorm을 깔기 싫은 독자는 커맨드라인을 이용한다. GitHub - expressjs/generator: Express’ application generator을 사용한다.
$ npm install -g express-generator
$ express --view=jade 만들프로젝트경로 && cd 만들프로젝트경로
$ npm install
API 서버를 만들것이기에 Template엔진은 default로 설정되어있는 jade를 우선 깔고 나중에 필요없는 코드를 삭제한다.
$ npm start
그다음 http://localhost:3000/ 에 접속하면 Express의 Wellcome to Express 화면을 볼 수 있다. 다음 화면을 볼 수 있으면 여기까지 잘 설치된 것이다.
$ tsc --init
message TS6071: Successfully created a tsconfig.json file.
위 커맨드로 tsconfig.json 파일이 생성되고 열어보면 다음과 같다.
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false
}
}
CommonJS 는 브라우저 뿐만 아니라 서버사이드 애플리케이션이나 데스크톱 애플리케이션에서 사용되기 위한 javascript 명세이다. ts를 es5의 js로 컴파일 한다는 설정이다.
$ tslint —init
위 커맨드를 입력하면 tslint.json파일이 생성되고, 이 파일에는 json구조로 규칙이 저장되어있다. 규칙을 수정하고 싶으면 tslint를 설정하는 규칙은 Tslint Rules을 참조하여 수정하면 된다. 간단히 설명하자면 대부분 첫번째 인자로의 true, false는 규칙 적용 여부, 그 뒤의 string은 옵션이다. 필자는 string이나 path에서 double quote(“)가 아닌 single quote(‘)를 사용하므로 이를 수정한다.
~~~
{
“quotemark”: [
true,
“single” //기존 “double”
],
}
~~~
Webstorm에서는 다음과 같이 설정하면 빨간 밑줄을 띄워주고, 대체로 editor나 IDE단에서 linter정도는 지원해 주므로 밑줄또는 경고등을 띄워준다.
커맨드라인에서 linter를 적용하고 싶으면 다음을 입력하면 된다.
$ tslint -c path/to/tslint.json ‘path/to/project/**/*.ts’
linter를 적용하고 나면 여러 경고를 만날 수 있는데, 이 경고에 따라 수정하면 된다.
대체로 처음 설정후 만나는 linter의 경고에서는 변수가 아닌 값들을 var가 아닌 const나 let으로 강제하는 것들이 대부분이다.
app.js의 마지막줄 module.export를 export default로 바꿈, routes/index.ts,routes/users.ts도 module.export를 export default로 바꾼다.
export default app; // module.exports = app;
node는 기본적으로 코드를 변경하고 난 후에 서버를 재시작해야 그 코드가 반영된다. 매번 ctr + c, 서버 재시작하기 귀찮음을 많이 느껴보았으므로 livereload 기능은 써보니 엄청나게 편하다! 이를 설정하는 방법은 다음과 같다.
{
…
"scripts": {
"start": "npm run build:live",
"concurrently \"tsc -w\" \"nodemon ./bin/www.js --config nodemon.json\""
},
...
}
위의 스크립트를 넣음으로써 동작은 다음과 같다. 1. npm start를 입력하면 typescript 컴파일러에 의해 코드의 변경을 감지하면 자동으로 컴파일을 진행(typescript => javascript) 2. nodemon은 컴파일된 javascript 파일의 변화를 감지하고 재시작한다
위의 방법이 싫으신 분은 ts-node사용하는 방법도 있다. Bonus: Live compile + run
$ npm strt
yuhogyun-ui-MacBook-Pro:boilerplate yuhogyun$ npm start
> boilerplate@0.0.0 start /Users/yuhogyun/boilerplate
> npm run build:live
> boilerplate@0.0.0 build:live /Users/yuhogyun/boilerplate
> concurrently "tsc -w" "nodemon ./bin/www.js --config nodemon.json"
[1] [nodemon] 1.11.0
[1] [nodemon] to restart at any time, enter `rs`
[1] [nodemon] watching: *.*
[1] [nodemon] starting `node ./bin/www.js`
우선 MongoDB Download Center | MongoDB 이 링크에서 몽고디비를 설치한다. 그다음 몽고디비 서버를 켠다
$ mongod
mongoose 는 Mongo를 node에서 사용하기 위한 object model이라고 보면 된다.
typescript에서 mongoose를 이용하려면 DefinitelyTyped/mongoose를 따라해보자.
/** Mongoose Config **/
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/boilerplate');
import {Document, model, Model, Schema} from 'mongoose';
var UserSchema: Schema = new Schema({
username: {
type: String,
required: true,
unique: true
},
age: Number,
friends: [String],
data: [Schema.Types.Mixed]
});
interface IUser extends Document {
username: string;
age: number;
friends: string[];
data: any[];
}
var UserModel: Model<IUser> = model<IUser>('User', UserSchema);
var user = new UserModel({user.username: 'Jane'});
user.username; // IUser properties are available
user.save(); // mongoose Document methods are available
UserModel.findOne({}, (err: any, user: IUser) => {
user.username; // IUser properties are available
user.save(); // mongoose Document methods are available
});
블로그 글을 쓰며 개인용으로도 쓸겸 typescript node mongo express로 기본 CRUD API 서버를 만들어보았다.
위의 긴 과정을 생략하고 싶은 독자들은 다음 링크를 참조하자.
https://github.com/yoohoogun114/node-express-mongo-typescript
Typescript가 트렌드가 될지 안 될지는 모르겠지만, 우선 javascript에서 타입 부여가 가능하다는 것은 매우 큰 장점이다. Typescript 말고도 관련 오픈소스 프로젝트들을 둘러보았는데 아주 활발한 것 같아서 아마 미래는 밝은 듯 하다. 또한 그동안 MEAN스택에서 빠져있던 mongo를 채우니 이제 드디어 완성인 것 같은 느낌이다.
TypeScript with NodeJS Include TypeScript files by default by arosequist · Pull Request #871 · remy/nodemon · GitHub