๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Dev.log/Node.js

[Node.js ๊ต๊ณผ์„œ] #22. ์ต์Šคํ”„๋ ˆ์Šค ์›น ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ - ํ…œํ”Œ๋ฆฟ ์—”์ง„ ์‚ฌ์šฉํ•˜๊ธฐ

ํ…œํ”Œ๋ฆฟ ์—”์ง„ ์‚ฌ์šฉํ•˜๊ธฐ

HTML์€ ์ •์ ์ธ ์–ธ์–ด์ด๋‹ค. ์ฃผ์–ด์ง„ ๊ธฐ๋Šฅ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ๋Šฅ์„ ์ง์ ‘ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋‹ค. ๋ฌผ๋ก  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์—†์„ ๋•Œ์˜ ์ด์•ผ๊ธฐ์ด๋‹ค.

HTML๋กœ 1000๊ฐœ๋‚˜ ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ํ‘œํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ผ์ผ์ด ์ง์ ‘ ์ฝ”๋”ฉํ•ด์„œ ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ํ…œํ”Œ๋ฆฟ ์—”์ง„์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ HTML์„ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ๋”ฐ๋ผ์„œ ๊ธฐ์กด HTML๊ณผ๋Š” ๋ฌธ๋ฒ•์ด ์‚ด์ง ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๊ณ , ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ๋ฒ•์ด ๋“ค์–ด ์žˆ๊ธฐ๋„ ํ•˜๋‹ค.

๋Œ€ํ‘œ์ ์ธ ํ…œํ”Œ๋ฆฟ ์—”์ง„์ธ Pug์™€ EJS์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์ž.

1. Pug(Jade)

์˜ˆ์ „ ์ด๋ฆ„์ธ Jade๋กœ ๋” ์œ ๋ช…ํ•œ Pug๋Š” ๊พธ์ค€ํ•œ ์ธ๊ธฐ๋ฅผ ์–ป๊ณ  ์žˆ๋‹ค. ๋ฌธ๋ฒ•์ด ๊ฐ„๋‹จํ•˜์—ฌ ์ฝ”๋“œ์˜ ์–‘์ด ์ค„์–ด๋“ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. Ruby๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์•˜๋‹ค๋ฉด ๋ฌธ๋ฒ•์ด ๋น„์Šทํ•ด ๊ธˆ๋ฐฉ ์ ์„ํ•  ๊ฒƒ์ด๋‹ค. ๋ฌผ๋ก  Ruby๋ฅผ ๋ชจ๋ฅด๋Š” ์‚ฌ๋žŒ๋„ ๋ฌธ๋ฒ•์ด ์‰ฌ์›Œ์„œ ๋น ๋ฅด๊ฒŒ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋‹ค. ๋‹จ, HTML๊ณผ๋Š” ๋ฌธ๋ฒ•์ด ๋งŽ์ด ๋‹ฌ๋ผ ํ˜ธ๋ถˆํ˜ธ๊ฐ€ ๊ฐˆ๋ฆฐ๋‹ค.

 

๋จผ์ € app.js์— ๋‹ค์Œ ๋ถ€๋ถ„์ด ๋“ค์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค.

 

 

views๋Š” ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ๋“ค์ด ์œ„์น˜ํ•œ ํด๋”๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. res.render ๋ฉ”์„œ๋“œ๊ฐ€ ์ด ํด๋” ๊ธฐ์ค€์œผ๋กœ ํ…œํ”Œ๋ฆฟ ์—”์ง„์„ ์ฐพ์•„์„œ ๋ Œ๋”๋งํ•œ๋‹ค. res.render('index')๋ผ๋ฉด views/index.pug๋ฅผ ๋ Œ๋”๋งํ•œ๋‹ค. res.render('admin/main')๋ผ๋ฉด views/admin/main.pug๋ฅผ ๋ Œ๋“œ๋งํ•œ๋‹ค.

view engine์€ ์–ด๋– ํ•œ ์ข…๋ฅ˜์˜ ํ…œํ”Œ๋ฆฟ ์—”์ง„์„ ์‚ฌ์šฉํ• ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ํ˜„์žฌ pug๋กœ ์„ฒใ…‡๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. 

1.1 HTML ํ‘œํ˜„

๊ธฐ์กด HTML๊ณผ ๋‹ค๋ฅด๊ฒŒ ํ™”์‚ด๊ด„ํ˜ธ(<>)์™€ ๋‹ซ๋Š” ํƒœ๊ทธ๊ฐ€ ์—†๋‹ค. ํƒญ ๋˜๋Š”  ์ŠคํŽ˜์ด์Šค๋กœ๋งŒ ํƒœ๊ทธ์˜ ๋ถ€๋ชจ ์ž์‹ ๊ด€๊ณ„๋ฅผ ๊ทœ๋ช…ํ•œ๋‹ค. ํƒญ ํ•œ ๋ฒˆ, ์ŠคํŽ˜์ด์Šค ๋‘ ๋ฒˆ ๋˜๋Š” ์ŠคํŽ˜์ด์Šค ๋„ค ๋ฒˆ ๋ชจ๋‘ ์ƒ๊ด€ ์—†๋‹ค. ๋ชจ๋“  ํŒŒ์ผ์— ๋™์ผํ•œ ์ข…๋ฅ˜์˜ ๋“ค์—ฌ์“ฐ๊ธฐ๋ฅผ ์ ์šฉํ•˜๋ฉด ๋œ๋‹ค. ์ž์‹ ํƒœ๊ทธ๋Š” ๋ถ€๋ชจ ํƒœ๊ทธ๋ณด๋‹ค ๋“ค์—ฌ์“ฐ๊ธฐ ๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๋“ค์—ฌ์“ฐ๊ธฐ์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ์œผ๋ฉด ์ œ๋Œ€๋กœ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์œผ๋‹ˆ ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค.

doctype html์€ <!DOCTYPE html>๊ณผ ๊ฐ™๋‹ค. html, head, title ํƒœ๊ทธ์—์„œ๋Š” ์ž์‹ ํƒœ๊ทธ์ผ์ˆ˜๋ก ํ•œ ๋‹จ๊ณ„์”ฉ ๋” ๋“ค์—ฌ์“ฐ๊ธฐ ๋˜์–ด ์žˆ๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. 

ํ™”์‚ด๊ด„ํ˜ธ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ํƒœ๊ทธ์˜ ์†์„ฑ๋„ ์กฐ๊ธˆ ๋‹ค๋ฅด๊ฒŒ ํ‘œํ˜„ํ•œ๋‹ค. ํƒœ๊ทธ๋ช… ๋’ค์— ์†Œ๊ด„ํ˜ธ๋กœ ๋ฌถ์–ด ์ ์–ด์ค€๋‹ค.

 

 

์†์„ฑ ์ค‘ ์•„์ด๋””์™€ ํด๋ž˜์Šค๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. div ํƒœ๊ทธ์ธ ๊ฒฝ์šฐ div ๋ฌธ์ž๋Š” ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

HTML ํ…์ŠคํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํƒœ๊ทธ ๋˜๋Š” ์†์„ฑ ๋’ค์— ํ•œ ์นธ์„ ๋„๊ณ  ์ž…๋ ฅํ•˜๋ฉด ๋œ๋‹ค.

 

 

์—๋””ํ„ฐ์—์„œ ํ…์ŠคํŠธ๋ฅผ ์—ฌ๋Ÿฌ ์ค„ ์ž…๋ ฅํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํŒŒ์ดํ”„(|)๋ฅผ ๋„ฃ์–ด์ค€๋‹ค. HTML ์ฝ”๋“œ์—์„œ๋Š” ํ•œ ์ค„๋กœ ๋‚˜์˜จ๋‹ค.

 

1.2 ๋ณ€์ˆ˜

HTML๊ณผ ๋‹ค๋ฅด๊ฒŒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ณ€์ˆ˜๋ฅผ ํ…œํ”Œ๋ฆฟ์— ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋‹ค. res.render ํ˜ธ์ถœ ์‹œ ๋ณด๋‚ด๋Š” ๋ณ€์ˆ˜๋ฅผ Pug๊ฐ€ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค. routes/index.js์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๋‹ค์Œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค.

 

 

res.render(ํ…œํ”Œ๋ฆฟ, ๋ณ€์ˆ˜ ๊ฐ์ฒด)๋Š” ์ต์Šคํ”„๋ ˆ์Šค๊ฐ€ res ๊ฐ์ฒด์— ์ถ”๊ฐ€ํ•œ ํ…œํ”Œ๋ฆฟ ๋ Œ๋”๋ง์„ ์œ„ํ•œ ๋ฉ”์„œ๋“œ์ด๋‹ค. index.pug๋ฅผ HTML๋กœ ๋ Œ๋”๋งํ•˜๋ฉด์„œ { title: 'Express' }๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ๋ณ€์ˆ˜๋กœ ์ง‘์–ด๋„ฃ๋Š”๋‹ค. layout.pug์™€ index.pug์˜ title ๋ถ€๋ถ„์ด ๋ชจ๋‘ Express๋กœ ์น˜ํ™˜๋œ๋‹ค. ์ฆ‰, HTML์—๋„ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ ์…ˆ์ด๋‹ค.

res.render ๋ฉ”์„œ๋“œ์— ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋ณ€์ˆ˜ ๊ฐ์ฒด๋ฅผ ๋„ฃ๋Š” ๋Œ€์‹ , app.js์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฏธ๋“ค์›จ์–ด์ฒ˜๋Ÿผ res.locals ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ณ€์ˆ˜๋ฅผ ๋„ฃ์„ ์ˆ˜๋„ ์žˆ๋‹ค. 

 

 

์œ„์™€ ๊ฐ™์ด ํ•˜๋ฉด ํ…œํ”Œ๋ฆฟ ์—”์ง„์ด res.locals ๊ฐ์ฒด๋ฅผ ์ฝ์–ด์„œ ๋ณ€์ˆ˜๋ฅผ ์ง‘์–ด ๋„ฃ๋Š”๋‹ค. ์ด ๋ฐฉ์‹์˜ ์žฅ์ ์€ ํ˜„์žฌ ๋ผ์šฐํ„ฐ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ๋ฏธ๋“ค์›จ์–ด์—์„œ๋„ res.locals ๊ฐ์ฒด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ๋ฏธ๋“ค์›จ์–ด์—์„œ ํ…œํ”Œ๋ฆฟ ์—”์ง„์šฉ ๋ณ€์ˆ˜๋ฅผ ๋ฏธ๋ฆฌ ๋„ฃ์„ ์ˆ˜๋„ ์žˆ๋‹ค. 

 

Pug์—์„œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž.

 

 

์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ๋ณ€์ˆ˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์œผ๋กœ Pug์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ณ€์ˆ˜๋ฅผ ํ…์ŠคํŠธ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ํƒœ๊ทธ ๋’ค์— =๋ฅผ ๋ถ™์ธ ํ›„ ๋ณ€์ˆ˜๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. ์†์„ฑ์—๋„ =๋ฅผ ๋ถ™์ธ ํ›„ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ํ…์ŠคํŠธ ์ค‘๊ฐ„์— ๋ณ€์ˆ˜๋ฅผ ๋„ฃ์œผ๋ ค๋ฉด #{๋ณ€์ˆ˜}๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ๋ณ€์ˆ˜๊ฐ€ ๊ทธ ์ž๋ฆฌ์— ๋“ค์–ด๊ฐ„๋‹ค. #{}์˜ ๋‚ด๋ถ€์™€ =๊ธฐํ˜ธ ๋’ท๋ถ€๋ถ„์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ํ•ด์„ํ•˜๋ฏ€๋กœ input ํƒœ๊ทธ์˜ ๊ฒฝ์šฐ์ฒ˜๋Ÿผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ตฌ๋ฌธ์„ ์จ๋„ ๋œ๋‹ค.

์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํด๋ผ์ด์–ธํŠธ๋กœ ๋‚ด๋ ค๋ณด๋‚ผ ๋•Œ #{}์™€ =๋ฅผ ๋งค์šฐ ๋นˆ๋ฒˆํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋‹ˆ ๊ผญ ๊ธฐ์–ตํ•ด๋‘๊ธฐ๋ฅผ ๋ฐ”๋ž€๋‹ค.

๋‚ด๋ถ€์— ์ง์ ‘ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๋นผ๊ธฐ(-)๋ฅผ ๋จผ์ € ์ž…๋ ฅํ•จ๋…€ ๋’ค์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ตฌ๋ฌธ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์— ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋ฉด ๋‹ค์Œ ์ค„๋ถ€ํ„ฐ ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

Pug๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ณ€์ˆ˜์˜ ํŠน์ˆ˜๋ฌธ์ž๋ฅผ HTML ์—”ํ„ฐํ‹ฐ๋กœ ์ด์Šค์ผ€์ดํ”„ํ•œ๋‹ค. ์ด์Šค์ผ€์ดํ”„๋ฅผ ์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด = ๋Œ€์‹  !=๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

1.3 ๋ฐ˜๋ณต๋ฌธ

HTML๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋ฐ˜๋ณต๋ฌธ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜์ธ ๊ฒฝ์šฐ์ผ ๋•Œ๋งŒ ํ•ด๋‹น๋œ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด each๋กœ ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค. each ๋Œ€์‹  for๋ฅผ ์จ๋„ ๋œ๋‹ค.

 

 

๋ฐ˜๋ณต๋ฌธ ์‚ฌ์šฉ ์‹œ ์ธ๋ฑ์Šค๋„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 

1.4 ์กฐ๊ฑด๋ฌธ

์กฐ๊ฑด๋ฌธ์œผ๋กœ ํŽธ๋ฆฌํ•˜๊ฒŒ ๋ถ„๊ธฐ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. if, else if, else๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค์Œ์€ isLoggedIn ๋ณ€์ˆ˜๋กœ ๋กœ๊ทธ์ธ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ HTML์„ ๋ Œ๋”๋งํ•˜๋Š” ์˜ˆ์‹œ์ด๋‹ค.

 

 

case๋ฌธ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

1.5 include

๋‹ค๋ฅธ Pug๋‚˜ HTML ํŒŒ์ผ์„ ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค. 

ํ—ค๋”๋‚˜ ํ‘ธํ„ฐ, ๋‚ด๋น„๊ฒŒ์ด์…˜์ฒ˜๋Ÿผ ์›น ์ œ์ž‘ ์‹œ ๊ณตํ†ต๋˜๋Š” ๋ถ€๋ถ„์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ๋งค ํŽ˜์ด์ง€๋งˆ๋‹ค ๋™์ผํ•œ HTML์„ ๋„ฃ์–ด์•ผ ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์„ ์—†์• ์ค€๋‹ค.

 

1.6 extends์™€ block

๋ ˆ์ด์•„์›ƒ์„ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ณตํ†ต๋˜๋Š” ๋ ˆ์ด์•„์›ƒ ๋ถ€๋ถ„์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์ข‹๋‹ค. include์™€๋„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ณค ํ•œ๋‹ค.

 

 

๋ ˆ์ด์•„์›ƒ์ด ๋  ํŒŒ์ผ์—๋Š” ๊ณตํ†ต๋œ ๋งˆํฌ์—…์„ ๋„ฃ๋˜, ํŽ˜์ด์ง€๋งˆ๋‹ค ๋‹ฌ๋ผ์ง€๋Š” ๋ถ€๋ถ„์„ block์œผ๋กœ ๋น„์›Œ๋‘”๋‹ค. block์€ ์—ฌ๋Ÿฌ ๊ฐœ ๋งŒ๋“ค์–ด๋„ ๋œ๋‹ค. block์„ ์„ ์–ธํ•˜๋Š” ๋ฐฉ๋ฒ•์€ block [๋ธ”๋ก๋ช…]์ด๋‹ค.

block์ด ๋˜๋Š” ํŒŒ์ผ์—์„œ๋Š” extends ํ‚ค์›Œ๋“œ๋กœ ๋ ˆ์ด์•„์›ƒ ํŒŒ์ผ์„ ์ง€์ •ํ•˜๊ณ  block ๋ถ€๋ถ„์„ ๋„ฃ์–ด์ค€๋‹ค. block ์„ ์–ธ๋ณด๋‹ค ํ•œ ๋‹จ๊ณ„ ๋” ๋“ค์—ฌ์“ฐ๊ธฐ ๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๋‚˜์ค‘์— ์ต์Šคํ”„๋ ˆ์Šค์—์„œ res, render('body')๋ฅผ ์‚ฌ์šฉํ•ด ํ•˜๋‚˜์˜ HTML๋กœ ํ•ฉ์ณ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋‹ค. Pug ํ™•์žฅ์ž๋Š” ์ƒ๋žต ๊ฐ€๋Šฅํ•˜๋‹ค. block ๋ถ€๋ถ„์ด ์„œ๋กœ ํ•ฉ์ณ์ง„๋‹ค.

 

์ด์ œ Pug์˜ ๋ฌธ๋ฒ•์€ ์ถฉ๋ถ„ํžˆ ๋ฐฐ์› ์œผ๋‹ˆ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒ์„ฑ๋œ Pug ํŒŒ์ผ๋“ค์„ ์‚ดํŽด๋ณด์ž.

 

views/layout.pug

 

views/index.pug

 

views/error.pug

 

index.pug๋ฅผ ๋ณด๋ฉด extends layout๊ณผ block content๊ฐ€ ์žˆ๋‹ค. layout.pug์˜ block content ๋ถ€๋ถ„์— index.pug์˜ block content๋ฅผ ๋„ฃ๋Š”๋‹ค. index.pug๋Š” title์ด๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์•„ ๋ Œ๋”๋งํ•œ๋‹ค.

error.pug๋„ block content ๋ถ€๋ถ„์ด layout.pug์™€ ์—ฐ๊ฒฐ๋œ๋‹ค. ๋ผ์šฐํ„ฐ๋กœ๋ถ€ํ„ฐ message์™€ error ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์•„ ๋ Œ๋”๋งํ•œ๋‹ค.

2. EJS

EJS๋Š” Pug์˜ HTML ๋ฌธ๋ฒ• ๋ณ€ํ™”์— ์ ์‘ํ•˜๊ธฐ ํž˜๋“  ๋ถ„์„ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ ์—”์ง„์ด๋‹ค. HTML ๋ฌธ๋ฒ•์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋˜ ์ถ”๊ฐ€๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ž๋ฐ”์˜ JSP์™€ ๋ฌธ๋ฒ•์ด ์ƒ๋‹นํžˆ ์œ ์‚ฌํ•˜๋‹ค.

 

app.js์—์„œ view engine์„ pug ๋Œ€์‹  ejs๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค.

 

 

ejs ํŒจํ‚ค์ง€๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์น˜ํ•ด์•ผ ํ•œ๋‹ค.

 

 

์ด์ œ EJS์˜ ๋ฌธ๋ฒ•์„ ๋ฐฐ์›Œ๋ณด์ž.

2.1 ๋ณ€์ˆ˜

EJS์—์„œ ๋ณ€์ˆ˜๋Š” <%= %>๋กœ ๊ฐ์‹ผ๋‹ค.

 

 

๋‚ด๋ถ€์— ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋Š” <% %> ์•ˆ์— ์ ์–ด์ค€๋‹ค.

 

 

HTML์„ ์ด์Šค์ผ€์ดํ”„ํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด <%- %>๋กœ ๊ฐ์‹ธ์ค€๋‹ค.

 

2.2 ๋ฐ˜๋ณต๋ฌธ

EJS์—์„œ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ <% %> ์•ˆ์— ์“ด๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ˜๋ณต๋ฌธ๋„ ์ด ์•ˆ์— ์“ฐ๋ฉด ๋œ๋‹ค. Pug์ฒ˜๋Ÿผ ๋”ฐ๋กœ ๋ฌธ๋ฒ•์ด ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ณ , for๋‚˜ while ๊ฐ™์€ ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

 

2.3 ์กฐ๊ฑด๋ฌธ

์กฐ๊ฑด๋ฌธ๋„ <% %> ์•ˆ์— ์“ด๋‹ค.

 

 

case๋ฌธ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

2.4 include

HTML ํŒŒ์ผ์„ ํฌํ•จํ•˜๋ ค๋ฉด <%- include(ํŒŒ์ผ ๊ฒฝ๋กœ, ๋ฐ์ดํ„ฐ) %>๋ฅผ ํ•˜๋ฉด ๋œ๋‹ค.

 

 

์•„์‰ฝ๊ฒŒ๋„ EJS๋Š” Pug์˜ layout๊ณผ block์€ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด express-ejs-layouts ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•œ๋‹ค. 

Express-generator๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒ์„ฑํ•œ Pug ํŒŒ์ผ์„ EJS๋กœ ๋ฐ”๊พธ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

 

 

head ํƒœ๊ทธ ๊ฐ™์ด ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„์€ ๋‚˜์ค‘์— ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ include๋กœ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค. 

Pug์™€ EJS ์ค‘ ์ทจํ–ฅ์— ๋งž๋Š” ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ง„ํ–‰ํ•˜๋ฉด ๋œ๋‹ค. ๋ณดํ†ต HTML์—์„œ ํฌ๊ฒŒ ๋ฒ—์–ด๋‚˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด EJS๋ฅผ, ๊น”๋”ํ•œ ๋ฌธ๋ฒ•์„ ์›ํ•œ๋‹ค๋ฉด Pug๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

Pug์™€ EJS ์™ธ์—๋„ Nunjucks, Hogan, Dust, Twig, Vash ๋“ฑ์˜ ํ…œํ”Œ๋ฆฟ ์—”์ง„์ด ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌธ๋ฒ•๋งŒ ๋‹ค๋ฅด๊ณ  ํ•ต์‹ฌ ๊ธฐ๋Šฅ์€ ๋‹ค ๋น„์Šทํ•˜๋‹ค. ๋‹ค๋ฅธ ๊ฒƒ๋„ ์‚ดํŽด๋ณธ ํ›„ ์ทจํ–ฅ์— ๋งž๋Š” ํ…œํ”Œ๋ฆฟ ์—”์ง„์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

3. ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฏธ๋“ค์›จ์–ด

์ง€๊ธˆ๊นŒ์ง€ ํ…œํ”Œ๋ฆฟ ์—”์ง„์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์•˜๋‹ค. ์ด์ œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฏธ๋“ค์›จ์–ด์˜ ์ฝ”๋“œ๊ฐ€ ์–ด๋–ค ๊ธฐ๋Šฅ์„ ํ•˜๋Š”์ง€ ๋ณด์ผ ๊ฒƒ์ด๋‹ค.

 

 

์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฏธ๋“ค์›จ์–ด๋Š” error๋ผ๋Š” ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์„ ๋ Œ๋”๋งํ•œ๋‹ค. ๋ Œ๋”๋ง ์‹œ res.locals.message์™€ res.locals.error์— ๋„ฃ์–ด์ค€ ๊ฐ’์„ ํ•จ๊ป˜ ๋ Œ๋”๋งํ•œ๋‹ค. res.render์— ๋ณ€์ˆ˜๋ฅผ ๋Œ€์ž…ํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„, ์ด๋ ‡๊ฒŒ res.locals ์†์„ฑ์— ๊ฐ’์„ ๋Œ€์ž…ํ•˜์—ฌ ํ…œํ”Œ๋ฆฟ ์—”์ง„์— ๋ณ€์ˆ˜๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค. 

error ๊ฐ์ฒด๋Š” ์‹œ์Šคํ…œ ํ™˜๊ฒฝ์ด development(๊ฐœ๋ฐœ ํ™˜๊ฒฝ)๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ํ‘œ์‹œ๋œ๋‹ค. ๋ฐฐํฌ ํ™˜๊ฒฝ์ธ ๊ฒฝ์šฐ์—๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š”๋‹ค. ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ๋…ธ์ถœ๋˜๋ฉด ๋ณด์•ˆ์— ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ฝ”๋“œ ์ค‘์— req.app.get(ํ‚ค)๋ผ๋Š” ๊ฒƒ์ด ์žˆ๋‹ค. req.app์„ ํ†ตํ•ด์„œ app ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด๋‹ค. app.get(ํ‚ค)๊ฐ€ app.set(ํ‚ค)๋กœ ์„ค์ •ํ–ˆ๋˜ ๊ฒƒ์„ ๊ฐ€์ ธ์˜ค๋Š” ์ฝ”๋“œ์ด๋ฏ€๋กœ req.app.get(ํ‚ค)๋กœ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, app.set('view engine', 'pug')๋ฅผ ํ–ˆ๋‹ค๋ฉด app.get('view engine')์œผ๋กœ pugใ„น๋Š” ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜๋„ ์žˆ๋‹ค. ๋ผ์šฐํ„ฐ์—์„œ๋Š” req.app.get('view engine')์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.

 

 

๋งŒ์•ฝ 404 ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด message๋Š” Not Found๊ฐ€ ๋œ๋‹ค. 404 ์ฒ˜๋ฆฌ ๋ฏธ๋“ค์›จ์–ด์—์„œ ๋„ฃ์–ด์ค€ ๊ฐ’์„ ์‚ฌ์šฉํ•œ๋‹ค. error.status๋Š” 404๊ฐ€ ๋˜๊ณ , error.stack์€ ์—๋Ÿฌ์— ๊ด€ํ•œ ์ƒ์„ธํ•œ ๋ฉ”์‹œ์ง€๊ฐ€  ํ‘œ์‹œ๋œ๋‹ค. ๋ฐฐํฌ ํ™˜๊ฒฝ์—์„œ๋Š” error ๋ถ€๋ถ„์ด ๋ Œ๋”๋ง๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.