Express Web Framework for Node.js
node.js 기반의 Express 웹프레임워크 사용하기
express 에서 템플릿 엔진 ( EJS, JADE ) 사용하기
- EJS(Embeded Javascript) : 동적으로 HTML 을 생성하는 템플릿 엔진
- express-generator 모듈을 설치하면 HTML 페이지를 동적으로 생성하는 EJS, JADE 템플릿 엔진을 사용할 수 있다
- express-generator 모듈 설치 : npm install -g express-generator
D:\NodeProjects>npm install -g express-generator
C:\Users\duniv6-000\AppData\Roaming\npm\express -> C:\Users\duniv6-000\AppData\R
oaming\npm\node_modules\express-generator\bin\express
express-generator@4.12.1 C:\Users\duniv6-000\AppData\Roaming\npm\node_modules\ex
press-generator
├── sorted-object@1.0.0
├── commander@2.6.0
└── mkdirp@0.5.0 (minimist@0.0.8)
- EJS 환경구성 : express --ejs
D:\NodeProjects\EJSDemo>express --ejs
create : .
create : ./package.json
create : ./app.js
create : ./public
create : ./public/images
create : ./public/stylesheets
create : ./public/stylesheets/style.css
create : ./public/javascripts
create : ./routes
create : ./routes/index.js
create : ./routes/users.js
create : ./views
create : ./views/index.ejs
create : ./views/error.ejs
create : ./bin
create : ./bin/www
install dependencies:
$ cd . && npm install
run the app:
$ DEBUG=EJSDemo:* ./bin/www
- npm install 명령을 사용하면 package.json 안에 정의된 모듈이 설치된다
D:\NodeProjects\EJSDemo>npm install
debug@2.1.3 node_modules\debug
└── ms@0.7.0
cookie-parser@1.3.4 node_modules\cookie-parser
├── cookie-signature@1.0.6
└── cookie@0.1.2
ejs@2.3.1 node_modules\ejs
serve-favicon@2.2.0 node_modules\serve-favicon
├── ms@0.7.0
├── fresh@0.2.4
├── parseurl@1.3.0
└── etag@1.5.1 (crc@3.2.1)
morgan@1.5.3 node_modules\morgan
├── basic-auth@1.0.1
├── depd@1.0.1
├── on-finished@2.2.1 (ee-first@1.1.0)
└── debug@2.2.0 (ms@0.7.1)
express@4.12.3 node_modules\express
├── merge-descriptors@1.0.0
├── utils-merge@1.0.0
├── cookie-signature@1.0.6
├── methods@1.1.1
├── fresh@0.2.4
├── escape-html@1.0.1
├── cookie@0.1.2
├── range-parser@1.0.2
├── content-type@1.0.1
├── vary@1.0.0
├── finalhandler@0.3.4
├── parseurl@1.3.0
├── serve-static@1.9.2
├── content-disposition@0.5.0
├── path-to-regexp@0.1.3
├── depd@1.0.1
├── qs@2.4.1
├── etag@1.5.1 (crc@3.2.1)
├── on-finished@2.2.1 (ee-first@1.1.0)
├── proxy-addr@1.0.8 (forwarded@0.1.0, ipaddr.js@1.0.1)
├── send@0.12.2 (destroy@1.0.3, ms@0.7.0, mime@1.3.4)
├── type-is@1.6.2 (media-typer@0.3.0, mime-types@2.0.11)
└── accepts@1.2.7 (negotiator@0.5.3, mime-types@2.0.11)
body-parser@1.12.4 node_modules\body-parser
├── content-type@1.0.1
├── bytes@1.0.0
├── depd@1.0.1
├── qs@2.4.2
├── on-finished@2.2.1 (ee-first@1.1.0)
├── debug@2.2.0 (ms@0.7.1)
├── raw-body@2.0.1 (bytes@2.0.1)
├── iconv-lite@0.4.8
└── type-is@1.6.2 (media-typer@0.3.0, mime-types@2.0.11)
- node bin/www 명령으로 위에서 생성된 www 파일을 실행(서버실행)한다
- 웹브라우저에서 요청하여 EJS의 작동상태를 확인한다
- http://localhost:3000
웹브라우저 요청결과 다음과 같은 내용이 화면에 출력되면 EJS 실행 테스트는 성공이다
Express
Welcome to Express
화면에 HTML 페이지가 출력되기 까지의 내부실행절차는 다음과 같다
- 웹브라우저 요청 --> routes/index.js --> views/index.ejs
화면에 출력된 내용은 서버측의 views/index.ejs 가 실행된 것이며 index.ejs 의 내용을 열어보면...
views/index.ejs의 내용
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
</body>
</html>
routes/index.js 의 내용
var express = require('express');
var app = express();
app.set('view engine', 'ejs');
/* GET home page. */
app.get('/', function(req, res) {
res.render('index', { title: 'Express' }); <-- index.ejs 가 호출되고 동적인 값이 전달됨
});
module.exports = router;
위의 내용은, GET 방식요청에 대한 응답으로 index.ejs가 호출되면서 title 변수에 'Express' 문자열이 저장되어 전달된다.
index.ejs의 내용을 약간 변경하여 for 루프를 사용하여 구구단을 출력하는 페이지를 작성해보면....
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<% for(var i=1;i<=9;i++) { %>
<%='7 * i = '+(7*i) %><br>
<% } %>
<p>Welcome to <%= title %></p>
</body>
</html>
위와 같이 뷰를 다시 작성하고 node bin/www 명령으로 서버를 다시 시작한 후에 웹브라우저로 요청한 결과 화면은....
Express
7 * i = 7
7 * i = 14
7 * i = 21
7 * i = 28
7 * i = 35
7 * i = 42
7 * i = 49
7 * i = 56
7 * i = 63
Welcome to Express
배열을 ejs 에 전달하여 화면에 출력되게 하려면 다음과 같은 방법을 이용하면 된다 ( 배열을 전달할 때는 JSON 오브젝트에 저장하여 전달한다)
app.get('/', function(req, res) {
var drinks = [
{ name: 'Bloody Mary', drunkness: 3 },
{ name: 'Martini', drunkness: 5 },
{ name: 'Scotch', drunkness: 10 }
];
var tagline = "Any code of your own that you haven't looked at for six or more months might as well have been written by someone else.";
res.render('printDrinks', { <-- printDrinks.ejs 호출, 배열을 다시 한번 오브젝트에 저장하여 전달하는 것에 주의, JADE 도 동일
drinks: drinks,
tagline: tagline
});
});
printDrinks.ejs ( 전달된 배열을 화면에 출력하는 예 )
...
<p><%= tagline %></p>
<h2>Loop</h2>
<ul>
<% drinks.forEach( function (drink ) { %>
<li><%= drink.name %> - <%= drink.drunkness %></li>
<% }); %>
</ul>
...
템플릿 엔진 JADE 설치 및 사용하기
jade 템플릿 엔진도 ejs와 동일하게 동적인 HTML 을 생성하는 기능을 갖지만 HTML 태그를 더 간략하게 표현할 수 있다.
jade tutorial
http://jade-lang.com/tutorial/
- express-generator 모듈 설치 : npm install -g express-generator
- express-generator 모듈을 이미지 전역으로(-g)으로 설치했다면 여기서 다시 설치할 필요는 없다
- jade 실행환경 생성 : express 명령을 아무런 옵션이 없이 실행하면 jade 를 사용한 애플리케이션이 생성된다
D:\NodeProjects\JADEDemo>express
create : .
create : ./package.json
create : ./app.js
create : ./public
create : ./public/stylesheets
create : ./public/stylesheets/style.css
create : ./public/images
create : ./public/javascripts
create : ./routes
create : ./routes/index.js
create : ./routes/users.js
create : ./views
create : ./views/index.jade
create : ./views/layout.jade
create : ./views/error.jade
create : ./bin
create : ./bin/www
install dependencies:
$ cd . && npm install
run the app:
$ DEBUG=JADEDemo:* ./bin/www
- npm install 명령으로 package.json 내의 모듈을 설치한다
D:\NodeProjects\JADEDemo>npm install
cookie-parser@1.3.4 node_modules\cookie-parser
├── cookie-signature@1.0.6
└── cookie@0.1.2
debug@2.1.3 node_modules\debug
└── ms@0.7.0
serve-favicon@2.2.0 node_modules\serve-favicon
├── fresh@0.2.4
├── ms@0.7.0
├── parseurl@1.3.0
└── etag@1.5.1 (crc@3.2.1)
body-parser@1.12.4 node_modules\body-parser
├── content-type@1.0.1
├── bytes@1.0.0
├── depd@1.0.1
├── qs@2.4.2
├── raw-body@2.0.1 (bytes@2.0.1)
├── debug@2.2.0 (ms@0.7.1)
├── iconv-lite@0.4.8
├── on-finished@2.2.1 (ee-first@1.1.0)
└── type-is@1.6.2 (media-typer@0.3.0, mime-types@2.0.11)
morgan@1.5.3 node_modules\morgan
├── basic-auth@1.0.1
├── depd@1.0.1
├── on-finished@2.2.1 (ee-first@1.1.0)
└── debug@2.2.0 (ms@0.7.1)
express@4.12.3 node_modules\express
├── merge-descriptors@1.0.0
├── utils-merge@1.0.0
├── cookie-signature@1.0.6
├── fresh@0.2.4
├── methods@1.1.1
├── cookie@0.1.2
├── escape-html@1.0.1
├── range-parser@1.0.2
├── content-type@1.0.1
├── finalhandler@0.3.4
├── vary@1.0.0
├── parseurl@1.3.0
├── serve-static@1.9.2
├── content-disposition@0.5.0
├── path-to-regexp@0.1.3
├── depd@1.0.1
├── on-finished@2.2.1 (ee-first@1.1.0)
├── qs@2.4.1
├── etag@1.5.1 (crc@3.2.1)
├── type-is@1.6.2 (media-typer@0.3.0, mime-types@2.0.11)
├── proxy-addr@1.0.8 (forwarded@0.1.0, ipaddr.js@1.0.1)
├── send@0.12.2 (destroy@1.0.3, ms@0.7.0, mime@1.3.4)
└── accepts@1.2.7 (negotiator@0.5.3, mime-types@2.0.11)
jade@1.9.2 node_modules\jade
├── character-parser@1.2.1
├── void-elements@2.0.1
├── commander@2.6.0
├── mkdirp@0.5.1 (minimist@0.0.8)
├── constantinople@3.0.1 (acorn-globals@1.0.4)
├── with@4.0.3 (acorn-globals@1.0.4, acorn@1.1.0)
└── transformers@2.1.0 (css@1.0.8, promise@2.0.0, uglify-js@2.2.5)
D:\NodeProjects\JADEDemo>
- 생성된 jade 애플리케이션을 실행한다 node bin/www
- 웹브라우저 주소창에 http://localhost:3000 을 입력하여 요청하면 다음과 같은 내용이 출력된다
Express
Welcome to Express
jade 애플리케이션 요청부터 응답 화면 출력까지의 절차
웹브라우저 요청 --> rouets/index.js --> views/index.jade --> 웹브라우저 출력
routes/index.js 내용
var express = require('express');
var app = express();
app.set('view engine', 'jade');
/* GET home page. */
app.get('/', function(req, res) {
res.render('index', { title: 'Express' }); <-- index.jade 호출됨
});
module.exports = router;
EJS, JADE에 공통적으로 적용되는 주의할 점
주의 : js 파일에서 생성된 배열을 jade 파일에 전달하여 화면에 출력하려는 경우에는 배열만 전달하면 안되고, 배열을 다시 JSON 오브젝트에 저장하여 jade에 전달해야 한다는 것에 주의해야 한다
예를 들면, 데이터베이스에서 가져온 회원 리스트(배열)를 jade 나 ejs 에 전달하려면....
userList 는 데이터베이스에 가져온 배열 오브젝트
response.render('userList', {userList : userList}); <-- 임의의 키에 대한 값으로 배열을 할당하여 JSON 오브젝트로 전달한다
위와 같이 배열을 전달할 때는 JSON 오브젝트에 특정 키와 함께 저장하여 jade나 ejs 파일로 전달해야 한다
userList.jade 에서는 다음과 같이 배열을 받아서 출력할 수 있다
extends layout
block content
h1
회원정보 리스트
ul
//each user, i in userList <-- 전달된 배열은 키가 아니라 값이 할당된다
for user, i in userList
li= user.name
views/layout.jade 내용 (들여쓰기, 내어쓰기로 태그간의 계층구조를 표현하므로 주의해야 한다)
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
views/index.jade 내용 ( block content 아래에 공백라인이 없도록 주의한다 )
extends layout <-- views/layout.jade 를 상속함
block content
h1= title <-- 태그의 바디에 들어가는 동적인 값
p Welcome to #{title} <-- 문자열 중간에 들어가는 동적인 값
jade 는 자바스크립트와 별개의 문법체계를 가진다 http://jade-lang.com/reference
jade에서 HTML 이 아닌 코드를 표현할 때는 #{코드} 형태를 사용한다
jade 안에서 배열의 할당과 출력은 다음과 같이 할 수 있다. jade 반복문 참조: http://jade-lang.com/reference/iteration/
extends layout
block content
h1= title
p Welcome to #{title}
#{ items = ["one", "two", "three"] }
each item, i in items
li #{item}: #{i}
jade 안에서 extends 키워드를 사용하여 다른 jade 파일을 상속할 수 있다
부모 jade 에서 block content 와 같은 형식으로 선언하고 자식 jade에서 block content 를 정의한다