{"id":1856,"date":"2022-03-23T05:46:50","date_gmt":"2022-03-23T05:46:50","guid":{"rendered":"https:\/\/migoda.vn\/xay-dung-website-voi-nodejs-1648014405"},"modified":"2023-04-22T11:30:09","modified_gmt":"2023-04-22T11:30:09","slug":"xay-dung-ung-dung-web-1648014405","status":"publish","type":"post","link":"https:\/\/migoda.vn\/blog\/xay-dung-ung-dung-web-1648014405\/","title":{"rendered":"X\u00e2y d\u1ef1ng \u1ee9ng d\u1ee5ng web v\u1edbi NodeJS + ExpressJS – VNTALKING"},"content":{"rendered":"
Hai b\u00e0i vi\u1ebft tr\u01b0\u1edbc m\u00ecnh \u0111\u00e3 c\u00f9ng nhau t\u00ecm hi\u1ec3u nh\u1eefng \u0111i\u1ec3m m\u1ea1nh c\u1ee7a Nodejs l\u00e0 g\u00ec r\u1ed3i. C\u00e1c b\u1ea1n c\u00f3 c\u1ea3m th\u1ea5y h\u01b0ng ph\u1ea5n \u0111\u1ec3 b\u1eaft \u0111\u1ea7u b\u01b0\u1edbc ch\u00e2n v\u00e0o th\u1ebf gi\u1edbi Nodejs ch\u01b0a? \u0110\u1ec3 m\u1edf m\u00e0n cho \u201cv\u0169 tr\u1ee5\u201d l\u1eadp tr\u00ecnh NodeJS, ch\u00fang ta s\u1ebd b\u1eaft tay v\u00e0o x\u00e2y d\u1ef1ng m\u1ed9t \u1ee9ng d\u1ee5ng web v\u1edbi NodeJS<\/strong> + ExpressJS \u0111\u01a1n gi\u1ea3n nh\u00e9.<\/span><\/p>\n L\u01b0u \u00fd: <\/b> B\u00e0i vi\u1ebft n\u00e0y s\u1ebd \u0111\u1eb7c bi\u1ec7t h\u1eefu \u00edch n\u1ebfu b\u1ea1n c\u00f3 ki\u1ec3n th\u1ee9c c\u01a1 b\u1ea3n v\u1ec1 Front-end nh\u01b0 Javascript, HTML, CSS. N\u1ebfu ch\u01b0a c\u00f3 th\u00ec c\u0169ng kh\u00f4ng sao, d\u1ea7n d\u1ea7n s\u1ebd quen th\u00f4i.<\/span><\/p>\n <\/span> ExpressJS l\u00e0 m\u1ed9t web framework \u0111\u01b0\u1ee3c x\u00e2y d\u1ef1ng tr\u00ean n\u1ec1n t\u1ea3ng NodeJs. Expressjs<\/strong> cung c\u1ea5p c\u00e1c h\u00e0m HTTP v\u00e0 midleware \u0111\u1ec3 t\u1ea1o ra API \u0111\u01a1n gi\u1ea3n v\u00e0 d\u1ec5 s\u1eed d\u1ee5ng.<\/span><\/p>\n B\u1ea1n \u0111ang \u0111\u1ecdc: X\u00e2y d\u1ef1ng \u1ee9ng d\u1ee5ng web v\u1edbi NodeJS + ExpressJS – VNTALKING<\/a><\/span><\/p>\n<\/div>\n ExpressJS \u0111\u01b0\u1ee3c ph\u00e1t h\u00e0nh theo gi\u1ea5y ph\u00e9p m\u00e3 ngu\u1ed3n m\u1edf, c\u00f3 h\u1ed9i \u0111\u1ed3ng t\u01b0\u01a1ng h\u1ed7 l\u1edbn, \u0111\u01b0\u1ee3c ph\u00e9p s\u1eed d\u1ee5ng cho \u1ee9ng d\u1ee5ng c\u00f3 m\u1ee5c ti\u00eau th\u01b0\u01a1ng m\u1ea1i. Do v\u1eady b\u1ea1n tr\u1ecdn v\u1eb9n ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 y\u00ean t\u00e2m s\u1eed d\u1ee5ng framework n\u00e0y cho d\u1ef1 \u00e1n B\u1ea5t \u0110\u1ed9ng S\u1ea3n c\u1ee7a m\u00ecnh, t\u1eeb d\u1ef1 \u00e1n B\u1ea5t \u0110\u1ed9ng S\u1ea3n nh\u1ecf t\u1edbi l\u1edbn .<\/span><\/p>\n C\u1ea5u tr\u00fac th\u01b0 m\u1ee5c d\u1ef1 \u00e1n B\u1ea5t \u0110\u1ed9ng S\u1ea3n khi s\u1eed d\u1ee5ng ExpressJS \u0111\u01b0\u1ee3c chia l\u00e0 3 ph\u1ea7n : routes, Views v\u00e0 Public. ExpressJS x\u00e2y d\u1ef1ng \u1ee9ng d\u1ee5ng web theo \u0111\u00fang quy m\u00f4 MVC ( Model \u2013 View \u2013 Controller ) .<\/span><\/p>\n <\/span><\/p>\n M\u1ed9t s\u1ed1 t\u00ednh n\u0103ng ch\u00ednh c\u1ee7a ExpressJS :<\/span><\/p>\n N\u1ebfu b\u1ea1n \u0111\u00e3 bi\u1ebft Javascript nh\u01b0ng to\u00e0n b\u1ed9 l\u1ea1i ch\u1ec9 g\u00f3i g\u1ecdn trong nh\u1eefng \u1ee9ng d\u1ee5ng front-end, th\u00ec b\u00e0i vi\u1ebft n\u00e0y sinh ra l\u00e0 \u0111\u1ec3 d\u00e0nh cho b\u1ea1n .<\/span><\/p>\n Trong nh\u1eefng ng\u00f4n t\u1eeb l\u1eadp tr\u00ecnh, c\u00e1 th\u1ec3 m\u00ecnh th\u1ea5y Javascript l\u00e0 m\u1ed9t ng\u00f4n t\u1eeb \u0111a n\u0103ng nh\u1ea5t cho t\u1edbi th\u1eddi gian hi\u1ec7n t\u1ea1i. N\u00f3 ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 gi\u00fap b\u1ea1n x\u00e2y d\u1ef1ng \u1ee9ng d\u1ee5ng t\u1eeb front-end t\u1edbi back-end, t\u1eeb mobile t\u1edbi web \u2026<\/span><\/p>\n Tr\u01b0\u1edbc khi m\u1edf m\u00e0n, b\u1ea1n c\u1ea7n ph\u1ea3i thi\u1ebft l\u1eadp Nodejs v\u00e0 NPM. N\u1ebfu b\u1ea1n ch\u01b0a c\u00e0i th\u00ec l\u00e0m theo h\u01b0\u1edbng d\u1eabn \u1edf b\u00e0i vi\u1ebft n\u00e0y : H\u01b0\u1edbng d\u1eabn chi ti\u1ebft c\u1ee5 th\u1ec3 thi\u1ebft l\u1eadp Node. js<\/span><\/p>\n H\u00e3y ch\u1eafc nh\u01b0 \u0111inh b\u1ea1n \u0111\u00e3 thi\u1ebft l\u1eadp th\u00e0nh c\u00f4ng xu\u1ea5t s\u1eafc Node. js v\u00e0 NPM b\u1eb1ng c\u00e1ch ki\u1ec3m tra vesion c\u1ee7a ch\u00fang b\u1eb1ng terminal :<\/span><\/p>\n M\u00ecnh tin l\u00e0 v\u1edbi nh\u1eefng phi\u00ean b\u1ea3n Node. js v\u00e0 NPM c\u0169 h\u01a1n th\u00ec b\u1ea1n v\u1eabn ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 code t\u1ed1t \u0111\u01b0\u1ee3c. Tuy nhi\u00ean, n\u1ebfu c\u00f3 b\u1ea5t k\u1ef3 l\u1ed7i x\u1ea3y khi l\u00e0m theo b\u00e0i vi\u1ebft c\u1ee7a m\u00ecnh vi\u1ec7c ti\u00ean phong b\u1ea1n ngh\u0129 t\u1edbi l\u00e0 t\u0103ng c\u1ea5p version c\u1ee7a Nodejs v\u00e0 NPM nh\u00e9 !<\/span><\/p>\n \u0110\u1ec3 nh\u1eefng b\u1ea1n \u0111\u1ee1 b\u1ecb cho\u00e1ng ng\u1ee3p khi m\u1edbi m\u1edf m\u00e0n l\u00e0m quen v\u1edbi Nodejs v\u00e0 ExpressJS. M\u00ecnh s\u1ebd c\u00f9ng nhau x\u00e2y d\u1ef1ng m\u1ed9t \u1ee9ng d\u1ee5ng web r\u1ea5t c\u01a1 b\u1ea3n c\u00f3 trang ch\u1ee7 page v\u00e0 m\u1ed9t v\u00e0i sub page v\u1edbi Nodejs .<\/span> \u0110\u00e2y l\u00e0 giao di\u1ec7n \u1ee9ng d\u1ee5ng web sau khi ho\u00e0n th\u00e0nh xong b\u00e0i vi\u1ebft .<\/span><\/p>\n C\u00e1c b\u1ea1n ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng l\u1ec7nh c\u1ee7a NPM \u0111\u1ec3 t\u1ea1o m\u1ed9t d\u1ef1 \u00e1n B\u1ea5t \u0110\u1ed9ng S\u1ea3n m\u1edbi tinh. \u0110\u01a1n gi\u1ea3n l\u00e0 g\u00f5 l\u1ec7nh sau v\u00e0 l\u00e0m theo h\u01b0\u1edbng d\u1eabn :<\/span><\/p>\n N\u1ebfu l\u01b0\u1eddi, b\u1ea1n ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 t\u1ea3i v\u1ec1 d\u1ef1 \u00e1n B\u1ea5t \u0110\u1ed9ng S\u1ea3n m\u00ecnh t\u1ea1o s\u1eb5n t\u1ea1i \u0111\u00e2y :<\/span> C\u00e1c b\u1ea1n m\u1edf file server.js l\u00ean v\u00e0 import v\u00e0 kh\u1edfi t\u1ea1o express.js nh\u01b0 b\u00ean d\u01b0\u1edbi :<\/span><\/p>\n H\u00e0m Ti\u1ebfp theo, t\u1ea5t c\u1ea3 ch\u00fang ta s\u1ebd t\u1ea1o m\u1ed9t server \u0111\u1ec3 ch\u1ea1y website. Nh\u01b0 c\u1ee7a m\u00ecnh th\u00ec server s\u1ebd ch\u1ea1y tr\u00ean port 7000, b\u1ea1n ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 \u0111\u1ed5i port sang b\u1ea5t k\u1ef3 port n\u00e0o c\u0169ng \u0111\u01b0\u1ee3c .<\/span><\/p>\n Ch\u00fang ta th\u1eed start server l\u00ean xem th\u1ebf n\u00e0o. T\u1eeb terminal, b\u1ea1n g\u00f5 l\u1ec7nh sau :<\/span><\/p>\n Khi server \u0111\u00e3 kh\u1edfi \u0111\u1ed9ng th\u00e0nh c\u00f4ng, b\u1ea1n v\u00e0o tr\u00ecnh duy\u1ec7t v\u00e0 truy c\u1eadp v\u00e0o \u0111\u1ecba ch\u1ec9: \u0110\u1ec3 \u0111\u1ecbnh ngh\u0129a m\u1ed9t router GET b\u1eb1ng expressJS, b\u1ea1n s\u1eed d\u1ee5ng \u0111o\u1ea1n code sau :<\/span><\/p>\n \u0110o\u1ea1n code tr\u00ean c\u00f3 ngh\u0129a l\u00e0, khi b\u1ea1n truy v\u1ea5n v\u00e0o trang ch\u1ee7 ( \u0111\u1ecba ch\u1ec9 \u201c \/ \u201d ) qua ph\u01b0\u01a1ng ph\u00e1p GET, server s\u1ebd tr\u1ea3 v\u1ec1 m\u1ed9t message l\u00e0 \u201c \u201d Hello World \u201d .<\/span><\/p>\n L\u01b0u \u00fd:<\/b> M\u1eb7c d\u00f9 b\u1ea1n c\u00f3 th\u1ec3 t\u1ea1o router cho b\u1ea5t k\u00ec lo\u1ea1i request n\u00e0o c\u1ee7a HTTP nh\u01b0 POST, PUT, DELETE. Tuy nhi\u00ean, b\u00e0i vi\u1ebft n\u00e0y m\u00ecnh ch\u1ec9 s\u1eed d\u1ee5ng ph\u01b0\u01a1ng ph\u1ee9c GET cho \u0111\u01a1n gi\u1ea3n.<\/span><\/p>\n OK, sau khi thi\u1ebft l\u1eadp router xong, b\u1ea1n kh\u1edfi \u0111\u1ed9ng l\u1ea1i server \u0111\u1ec3 bi\u1ebfn h\u00f3a code c\u00f3 hi\u1ec7u l\u1ef1c hi\u1ec7n h\u00e0nh. K\u1ebft qu\u1ea3 thu \u0111\u01b0\u1ee3c nh\u01b0 sau :<\/span><\/p>\n <\/span><\/p>\n Nh\u01b0 b\u1ea1n c\u0169ng th\u1ea5y \u1edf tr\u00ean, m\u1ed7i l\u1ea7n b\u1ea1n bi\u1ebfn h\u00f3a code th\u00ec \u0111\u1ec1u ph\u1ea3i kh\u1edfi \u0111\u1ed9ng l\u1ea1i server \u0111\u1ec3 \u0111o\u1ea1n code thay c\u00f3 hi\u1ec7u l\u1ef1c th\u1ef1c thi hi\u1ec7n h\u00e0nh .<\/span><\/p>\n \u0110\u1ec3 ti\u1ebft ki\u1ec7m chi ph\u00ed th\u1eddi h\u1ea1n t\u0103ng tr\u01b0\u1edfng \u1ee9ng d\u1ee5ng, t\u1ea5t c\u1ea3 ch\u00fang ta ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng c\u00f4ng c\u1ee5 gi\u00fap t\u1ef1 kh\u1edfi \u0111\u1ed9ng l\u1ea1i server m\u1ed7i khi \u0111\u1ed5i kh\u00e1c code. C\u00f3 r\u1ea5t nhi\u1ec1u c\u00f4ng c\u1ee5 nh\u01b0 v\u1eady, ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 k\u1ec3 \u0111\u1ebfn nh\u01b0 : nodemon, forever, PM2 \u2026 C\u00e1 nh\u00e2n m\u00ecnh th\u00ec th\u00edch s\u1eed d\u1ee5ng PM2 v\u00ec t\u00ednh hi\u1ec7u su\u1ea5t cao c\u1ee7a n\u00f3.<\/span><\/p>\n N\u1ebfu b\u1ea1n \u0111\u1ec3 \u00fd trong file package.json<\/strong>, b\u1ea1n s\u1ebd th\u1ea5y m\u00ecnh \u0111\u1ec3 s\u1eb5n PM2 trong devDependencies, n\u00ean b\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng PM2 lu\u00f4n \u0111\u01b0\u1ee3c.<\/span><\/p>\n B\u1ea1n t\u1ea1o m\u1ed9t script trong package.json nh\u01b0 sau :<\/span><\/p>\n Cu\u1ed1i c\u00f9ng, b\u1ea1n ch\u1ea1y l\u1ea1i server b\u1eb1ng l\u1ec7nh :<\/span><\/p>\n T\u1eeb gi\u1edd \u0111\u00e2y tr\u1edf \u0111i, b\u1ea1n c\u1ee9 \u0111\u1ed5i kh\u00e1c code t\u1ef1 do l\u00e0 ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 test \u0111\u01b0\u1ee3c ngay m\u00e0 kh\u00f4ng c\u1ea7n ph\u1ea3i kh\u1edfi \u0111\u1ed9ng l\u1ea1i server n\u1eefa. Qu\u00e1 ti\u1ec7n ph\u1ea3i kh\u00f4ng ?<\/span><\/p>\n >> \u0110\u1ecdc th\u00eam: <\/strong>T\u1ef1 x\u00e2y d\u1ef1ng RESTful APIs v\u1edbi Nodejs<\/strong><\/span><\/p>\n Th\u00f4ng th\u01b0\u1eddng, khi ng\u01b0\u1eddi d\u00f9ng li\u00ean k\u1ebft v\u00e0o m\u1ed9t URL c\u1ee7a website, server s\u1ebd tr\u1ea3 v\u1ec1 l\u00e0 m\u1ed9t trang HTML. Thay v\u00ec t\u1ea5t c\u1ea3 ch\u00fang ta s\u1ebd ch\u1ec9 \u0111\u1ecbnh tr\u1ea3 v\u1ec1 m\u1ed9t file HTML s\u1eb5n th\u00ec t\u1ea5t c\u1ea3 ch\u00fang ta s\u1ebd s\u1eed d\u1ee5ng d\u1ee5ng nh\u1eefng template engine \u0111\u1ec3 t\u01b0\u01a1ng h\u1ed7 render nh\u1eefng file HTML .<\/span><\/p>\n M\u1ed9t template engine cho ph\u00e9p ch\u00fang ta t\u1ea1o m\u1ed9t trang HTML v\u00e0 thay th\u1ebf c\u00e1c bi\u1ebfn v\u1edbi gi\u00e1 tr\u1ecb th\u1eadt trong template khi tr\u1ea3 v\u1ec1 cho ng\u01b0\u1eddi d\u00f9ng. N\u1ebfu b\u1ea1n \u0111\u00e3 t\u1eebng s\u1eed d\u1ee5ng data binding trong l\u1eadp tr\u00ecnh Android th\u00ec template engine c\u0169ng ho\u1ea1t \u0111\u1ed9ng t\u01b0\u01a1ng t\u1ef1.<\/span><\/p>\n Xem th\u00eam: H\u01b0\u1edbng d\u1eabn t\u1ea1o website: C\u00e1ch t\u1ea1o trang web t\u1eeb A – Z cho ng\u01b0\u1eddi m\u1edbi<\/a><\/span><\/p>\n<\/div>\n C\u00f3 m\u1ed9t s\u1ed1 \u00edt template engine ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 thao t\u00e1c v\u1edbi ExpressJS nh\u01b0 : Pug ( Jade ), EJS, Mustache \u2026<\/span> V\u00e0 khai b\u00e1o trong server.js<\/strong><\/span><\/p>\n Trong ExpressJS, nh\u1eefng template HTML s\u1ebd \u0111\u01b0\u1ee3c \u0111\u1eb7t trong th\u01b0 m\u1ee5c Views. Trong v\u00ed d\u1ee5 n\u00e0y, m\u00ecnh th\u1eed t\u1ea1o m\u1ed9t file template c\u00f3 t\u00ean l\u00e0 : index.pug c\u00f3 n\u1ed9i dung nh\u01b0 sau :<\/span><\/p>\n \u0110\u1ec3 render ra file template n\u00e0y khi ng\u01b0\u1eddi d\u00f9ng v\u00e0o trang ch\u1ee7, ta s\u1eeda \u0111o\u1ea1n thi\u1ebft l\u1eadp router \u1edf tr\u00ean th\u00e0nh :<\/span><\/p>\n V\u00e0 hi\u1ec7u qu\u1ea3 thu \u0111\u01b0\u1ee3c nh\u01b0 sau :<\/span><\/p>\n <\/span><\/p>\n Note:<\/b> \u0110\u1ec3 s\u1eed d\u1ee5ng PUG, ch\u00fang ta c\u1ea7n bi\u1ebft m\u1ed9t v\u00e0i syntax c\u1ee7a n\u00f3. Tuy nhi\u00ean, do b\u00e0i vi\u1ebft n\u00e0y h\u01a1i d\u00e0i n\u00ean m\u00ecnh s\u1ebd h\u01b0\u1edbng d\u1eabn c\u00e1c b\u1ea1n c\u00e1ch s\u1eed d\u1ee5ng PUG \u1edf m\u1ed9t b\u00e0i vi\u1ebft kh\u00e1c nh\u00e9. C\u00e1c b\u1ea1n nh\u1edb \u0111\u00f3n \u0111\u1ecdc nh\u00e9!<\/span><\/p>\n \u0110\u1ecdc \u0111\u1ebfn \u0111\u00e2y th\u00ec b\u1ea1n \u0111\u00e3 c\u00f3 m\u1ed9t s\u1ed1 \u00edt k\u1ef9 n\u0103ng v\u00e0 ki\u1ebfn th\u1ee9c c\u01a1 b\u1ea3n v\u1ec1 ExpressJS, template engine. Ch\u00fang ta s\u1ebd b\u1eaft tay v\u00e0o x\u00e2y d\u1ef1ng website nh\u01b0 \u1edf \u0111\u1ea7u b\u00e0i vi\u1ebft \u0111\u00e3 tr\u00ecnh di\u1ec5n .<\/span> T\u1eeb kh\u00f3a block gi\u1ed1ng nh\u01b0 include trong layout android v\u1eady. Ngh\u0129a l\u00e0 t\u1ea5t c\u1ea3 ch\u00fang ta ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 ch\u00e8n m\u1ed9t file template kh\u00e1c v\u00e0o. \u0110i\u1ec1u n\u00e0y gi\u00fap t\u1ea5t c\u1ea3 ch\u00fang ta t\u00e1i s\u1eed d\u1ee5ng template t\u1ed1t h\u01a1n .<\/span> Ch\u00fang ta l\u1ea1i s\u1eeda l\u1ea1i \u0111o\u1ea1n code thi\u1ebft l\u1eadp router \u1edf tr\u00ean th\u00e0nh nh\u01b0 sau :<\/span><\/p>\n Nh\u01b0 \u1edf \u0111\u00e2y, t\u1ea5t c\u1ea3 bi\u1ebfn <\/span><\/p>\n Tr\u00ean \u0111\u00e2y, t\u1ea5t c\u1ea3 ch\u00fang ta m\u1edbi ch\u1ec9 tr\u1ea3 v\u1ec1 m\u1ed7i HTML cho tr\u00ecnh duy\u1ec7t. \u0110\u1ec3 website \u0111\u1eb9p h\u01a1n, t\u1ea5t c\u1ea3 ch\u00fang ta c\u1ea7n ph\u1ea3i c\u00f3 CSS .<\/span> Xong, b\u1ea1n th\u1eed refesh l\u1ea1i tr\u00ecnh duy\u1ec7t v\u00e0 t\u1eadn th\u01b0\u1edfng t\u00e1c d\u1ee5ng :<\/span><\/p>\n <\/span><\/p>\n C\u00e1c website gi\u1edd \u0111\u00e2y ph\u1ea7n l\u1edbn l\u00e0 web \u0111\u1ed9ng, t\u1ee9c l\u00e0 server s\u1ebd l\u01b0u t\u00e0i li\u1ec7u trong database, r\u1ed3i l\u1ea1i l\u1ea5y ra \u0111\u01b0a l\u00ean nh\u1eefng template engine .<\/span> \u0110\u1ea1i kh\u00e1i nh\u01b0 v\u1eady, nh\u1eefng b\u1ea1n t\u1ef1 \u0111\u1ed5i n\u1ed9i dung theo \u00fd m\u00ecnh nh\u00e9 !<\/span> Nh\u01b0 \u0111o\u1ea1n code tr\u00ean, t\u1ea5t c\u1ea3 ch\u00fang ta reference file JSON v\u00e0o bi\u1ebfn people. Sau \u0111\u00f3 pass m\u1ea3ng profiles v\u00e0o template engine tr\u1ea3i qua people .<\/span> K\u1ebft qu\u1ea3 thu \u0111\u01b0\u1ee3c :<\/span><\/p>\n <\/span><\/p>\n Khi b\u1ea1n th\u1eed click v\u00e0o link : \u201c View Profile \u201d ngay l\u1eadp t\u1ee9c b\u1ea1n s\u1ebd b\u1ecb l\u1ed7i \u201c cannot GET \/ profile \u201c .<\/span> v\u00e0 template engine th\u00ec t\u1ea1o m\u1ed9t file m\u1edbi : profile.pug<\/span><\/p>\n Th\u1ebf l\u00e0 xong. Gi\u1edd t\u1ea5t c\u1ea3 ch\u00fang ta th\u1eed refesh tr\u00ecnh duy\u1ec7t v\u00e0 click v\u00e0o t\u1eebng profile xem t\u00e1c d\u1ee5ng nh\u00e9<\/span><\/p>\n Nh\u01b0 v\u1eady, qua b\u00e0i vi\u1ebft n\u00e0y m\u00ecnh \u0111\u00e3 h\u01b0\u1edbng d\u1eabn nh\u1eefng b\u1ea1n c\u00e1ch t\u1ea1o \u1ee9ng d\u1ee5ng web v\u1edbi NodeJS + ExpressJS \u0111\u01a1n thu\u1ea7n .<\/span><\/p>\n M\u1edbi \u0111\u1ea7u ti\u1ebfp c\u1eadn v\u1edbi Nodejs, c\u00e1c b\u1ea1n s\u1ebd th\u1ea5y h\u01a1i b\u01a1 ng\u1ee1. Nh\u01b0 khi \u0111\u00e3 quen r\u1ed3i th\u00ec b\u1ea1n s\u1ebd th\u1ea5y n\u00f3 th\u1ef1c s\u1ef1 tuy\u1ec7t v\u1eddi.<\/span><\/p>\n Xem th\u00eam: 7 B\u00ed quy\u1ebft x\u00e2y d\u1ef1ng website b\u00e1n h\u00e0ng hi\u1ec7u qu\u1ea3<\/a><\/span><\/p>\n<\/div>\n M\u00ecnh hy v\u1ecdng nh\u1eefng b\u1ea1n s\u1ebd th\u1ea5y c\u00f3 \u00edch khi \u0111\u1ecdc b\u00e0i vi\u1ebft n\u00e0y. N\u1ebfu nh\u1eefng b\u1ea1n \u1ee7ng h\u1ed9, m\u00ecnh s\u1ebd li\u00ean t\u1ee5c vi\u1ebft v\u1ec1 Nodejs \u0111\u1ec3 t\u1ea5t c\u1ea3 ch\u00fang ta c\u00f9ng h\u1ecdc h\u1ecfi .<\/span> Ngu\u1ed3n: Timgiatot.vn<\/span><\/p>\n Xem th\u00eam: 6 b\u01b0\u1edbc x\u00e2y d\u1ef1ng website D\u1ec4 D\u00c0NG v\u00e0 NHANH CH\u00d3NG nh\u1ea5t<\/a><\/span><\/p>\n<\/div>\n Source: https:\/\/migoda.vn<\/a> <\/span> Hai b\u00e0i vi\u1ebft tr\u01b0\u1edbc m\u00ecnh \u0111\u00e3 c\u00f9ng nhau t\u00ecm hi\u1ec3u nh\u1eefng \u0111i\u1ec3m m\u1ea1nh c\u1ee7a Nodejs l\u00e0 g\u00ec r\u1ed3i. C\u00e1c b\u1ea1n c\u00f3 c\u1ea3m th\u1ea5y h\u01b0ng ph\u1ea5n \u0111\u1ec3 b\u1eaft \u0111\u1ea7u b\u01b0\u1edbc ch\u00e2n…<\/p>\n","protected":false},"author":1,"featured_media":4964,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_mi_skip_tracking":false,"footnotes":""},"categories":[26],"tags":[140],"class_list":["post-1856","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-seo","tag-ung-dung-web"],"_links":{"self":[{"href":"https:\/\/migoda.vn\/blog\/wp-json\/wp\/v2\/posts\/1856"}],"collection":[{"href":"https:\/\/migoda.vn\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/migoda.vn\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/migoda.vn\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/migoda.vn\/blog\/wp-json\/wp\/v2\/comments?post=1856"}],"version-history":[{"count":0,"href":"https:\/\/migoda.vn\/blog\/wp-json\/wp\/v2\/posts\/1856\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/migoda.vn\/blog\/wp-json\/wp\/v2\/media\/4964"}],"wp:attachment":[{"href":"https:\/\/migoda.vn\/blog\/wp-json\/wp\/v2\/media?parent=1856"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/migoda.vn\/blog\/wp-json\/wp\/v2\/categories?post=1856"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/migoda.vn\/blog\/wp-json\/wp\/v2\/tags?post=1856"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}
\nTr\u01b0\u1edbc khi b\u1eaft tay v\u00e0o vi\u1ebft code, m\u00ecnh s\u1ebd \u0111i\u1ec3m qua nh\u1eefng th\u01b0 vi\u1ec7n, c\u00f4ng c\u1ee5 \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng trong b\u00e0i vi\u1ebft \u0111\u00e3 nh\u00e9.<\/span><\/p>\n# Express js l\u00e0 g\u00ec ?<\/span><\/h2>\n
\n
# \u0110\u1ec3 t\u1ea1o \u1ee9ng d\u1ee5ng web v\u1edbi NodeJS c\u1ea7n nh\u1eefng g\u00ec ?<\/span><\/h2>\n
node -v\r\nnpm -v\r\n<\/span><\/pre>\n
# Gi\u1edbi thi\u1ec7u \u1ee9ng d\u1ee5ng web v\u1edbi NodeJS s\u1ebd x\u00e2y d\u1ef1ng trong b\u00e0i vi\u1ebft<\/span><\/h3>\n
\n\u1ee8ng d\u1ee5ng n\u00e0y s\u1ebd s\u1eed d\u1ee5ng Express. js framework, v\u00e0 render HTML b\u1eb1ng th\u01b0 vi\u1ec7n PUG ( tr\u01b0\u1edbc kia th\u01b0 vi\u1ec7n c\u00f3 t\u00ean l\u00e0 Jade ) .<\/span><\/p>\n# Kh\u1edfi t\u1ea1o \u1ee9ng d\u1ee5ng<\/span><\/h4>\n
npm init<\/span><\/pre>\n
\nSau khi t\u1ea3i v\u1ec1, b\u1ea1n m\u1edf c\u1eeda s\u1ed5 terminal v\u00e0 chuy\u1ec3n \u0111\u1ebfn th\u01b0 m\u1ee5c d\u1ef1 \u00e1n B\u1ea5t \u0110\u1ed9ng S\u1ea3n, g\u00f5 l\u1ec7nh sau \u0111\u1ec3 thi\u1ebft l\u1eadp h\u00e0ng lo\u1ea1t th\u01b0 vi\u1ec7n ( dependencies ) thi\u1ebft y\u1ebfu :<\/span><\/p>\nnpm install<\/span><\/pre>\n
const express = require('express');\r\nconst app = express();\r\n<\/span><\/pre>\n
express()<\/code> l\u00e0 h\u00e0m cao nh\u1ea5t \u0111\u01b0\u1ee3c exported b\u1edfi express module<\/span><\/p>\n
const server = app.listen(7000, () => {\r\n console.log(`Express running \u2192 PORT ${server.address().port}`);\r\n});\r\n<\/span><\/pre>\n
node server.js<\/span><\/pre>\n
http:\/\/localhost:7000<\/code>. B\u1ea1n s\u1ebd tr\u00ecnh duy\u1ec7t b\u00e1o l\u1ed7i: \u201cCannot GET \/\u201c. L\u1ed7i n\u00e0y x\u1ea3y ra v\u00ec b\u1ea1n ch\u01b0a \u0111\u1ecbnh ngh\u0129a b\u1ea5t k\u00ec router cho website c\u1ea3. Ch\u01b0a c\u00f3 th\u00ec gi\u1edd m\u00ecnh t\u1ea1o th\u00f4i.<\/span><\/p>\n
app.get('\/', (req, res) => {\r\n res.send('Hello World!');\r\n});\r\n<\/span><\/pre>\n
# S\u1eed d\u1ee5ng pm2 \u0111\u1ec3 t\u1ef1 kh\u1edfi \u0111\u1ed9ng server khi \u0111\u1ed5i kh\u00e1c code<\/span><\/h4>\n
{\r\n \/\/ ...\r\n \"scripts\": {\r\n \"start\": \"npx pm2 start server.js --watch\"\r\n }\r\n \/\/ ...\r\n}\r\n<\/span><\/pre>\n
npm start<\/span><\/pre>\n
# Rendering HTML s\u1eed d\u1ee5ng Pug<\/span><\/h3>\n
\nTrong b\u00e0i vi\u1ebft n\u00e0y, m\u00ecnh s\u1ebd s\u1eed d\u1ee5ng Pug, \u0111\u01a1n thu\u1ea7n v\u00ec m\u00ecnh \u0111\u00e3 quen c\u00e1ch s\u1eed d\u1ee5ng c\u1ee7a n\u00f3. C\u00e1c b\u1ea1n sau n\u00e0y ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 t\u00f9y \u00fd l\u1ef1a ch\u1ecdn cho d\u1ef1 \u00e1n B\u1ea5t \u0110\u1ed9ng S\u1ea3n c\u1ee7a m\u00ecnh .<\/span>
\n\u0110\u1ec3 s\u1eed d\u1ee5ng Pug, t\u1ea5t c\u1ea3 ch\u00fang ta c\u1ea7n khai b\u00e1o trong package.json<\/span><\/p>\n\"dependencies\": {\r\n \"pug\": \"^2.0.3\"\r\n},\r\n<\/span><\/pre>\n
app.set('view engine', 'pug');<\/span><\/pre>\n
p Hello Pug!<\/span><\/pre>\n
app.get('\/', (req, res) => {\r\n res.render('index')\r\n});\r\n<\/span><\/pre>\n
# X\u00e2y d\u1ef1ng giao di\u1ec7n v\u00e0 logic c\u1ee7a \u1ee9ng d\u1ee5ng web<\/span><\/h2>\n
\n\u0110\u1ea7u ti\u00ean, t\u1ea5t c\u1ea3 ch\u00fang ta s\u1ebd t\u1ea1o giao di\u1ec7n trang ch\u1ee7, \u0111\u1eb7t t\u00ean l\u00e0 default.pug, code s\u1ebd nh\u01b0 sau :<\/span><\/p>\ndoctype html\r\nhtml\r\n head\r\n title #{title}\r\n link(rel='stylesheet', href='\/css\/style.css')\r\n meta(name=\"viewport\" content=\"width=device-width, initial-scale=1\")\r\n body\r\n main\r\n block header\r\n header.header\r\n h1 #{title}\r\n block content\r\n<\/span><\/pre>\n
\nC\u00f2n \u0111\u00e2y l\u00e0 file index.pug<\/span><\/p>\nextends default\r\n\r\nblock content\r\n div.container\r\n<\/span><\/pre>\n
app.get('\/', (req, res) => {\r\n res.render('index', {\r\n \ttitle: 'Homepage'\r\n});});\r\n<\/span><\/pre>\n
#{title}<\/code> trong file default.pug s\u1ebd \u0111\u01b0\u1ee3c thay th\u1ebf b\u1eb1ng text: \u201cHomepage\u201d r\u1ed3i tr\u1ea3 v\u1ec1 cho tr\u00ecnh duy\u1ec7t. K\u1ebft qu\u1ea3 nh\u01b0 sau:<\/span><\/p>\n
L\u00e0m vi\u1ec7c v\u1edbi static content<\/span><\/h3>\n
\n\u0110\u1ec3 s\u1eed d\u1ee5ng \u0111\u01b0\u1ee3c CSS trong ExpressJS, t\u1ea5t c\u1ea3 ch\u00fang ta th\u00eam \u0111o\u1ea1n code sau :<\/span><\/p>\n\/\/ ...\r\napp.set('view engine', 'pug');\r\n\r\n\/\/ serve static files from the `public` folder\r\napp.use(express.static(__dirname + '\/public'));\r\n\/\/ ...\r\n<\/span><\/pre>\n
L\u00e0m vi\u1ec7c v\u1edbi JSON data trong NodeJS<\/span><\/h3>\n
\nV\u00ec t\u1ea5t c\u1ea3 ch\u00fang ta kh\u00f4ng s\u1eed d\u1ee5ng database trong b\u00e0i vi\u1ebft n\u00e0y, n\u00ean m\u00ecnh s\u1ebd t\u1ea1o m\u1ed9t file JSON v\u1eady .<\/span>
\nM\u00ecnh s\u1ebd t\u1ea1o file people.json c\u00f3 c\u1ea5u tr\u00fac nh\u01b0 sau :<\/span><\/p>\n{\r\n \"profiles\": [\r\n {\r\n \"firstname\": \"Duong\",\r\n \"lastname\": \"Anh S\u01a1n\",\r\n \"bio\":\r\n \"Anh S\u01a1n l\u00e0 m\u1ed9t l\u1eadp tr\u00ecnh Android v\u00e0 gi\u1edd \u0111ang h\u01b0\u1edbng d\u1eabn v\u1ec1 NodeJS.\",\r\n \"tagline\": \"Developer, Writer and Speaker\",\r\n \"twitter\": \"https:\/\/twitter.com\/ngotuannghia\",\r\n \"imgSrc\": \"tom-jagger.jpg\",\r\n \"id\": \"tom\"\r\n },\r\n ]\r\n}\r\n<\/span><\/pre>\n
\nCh\u00fang ta khai b\u00e1o file JSON trong server.js. V\u00e0 t\u00e1c d\u1ee5ng server.js s\u1ebd nh\u01b0 sau :<\/span><\/p>\nconst express = require('express');\r\nconst people = require('.\/people.json');\r\n\r\nconst app = express();\r\n\r\napp.set('view engine', 'pug');\r\n\r\napp.use(express.static(__dirname + '\/public'));\r\n\r\napp.get('\/', (req, res) => {\r\n res.render('index', {\r\n title: 'Homepage',\r\n people: people.profiles\r\n });\r\n});\r\n\r\nconst server = app.listen(7000, () => {\r\n console.log(`Express running \u2192 PORT ${server.address().port}`);\r\n});\r\n<\/span><\/pre>\n
\nB\u00e2y gi\u1edd, b\u1ea1n \u0111\u1ed5i m\u1ed9t ch\u00fat \u00edt \u1edf index.pug nh\u01b0 sau :<\/span><\/p>\nextends default\r\n\r\nblock content\r\n div.container\r\n each person in people\r\n div.person\r\n div.person-image(style=`background: url('\/images\/${person.imgSrc}') top center\r\n no-repeat; background-size: cover;`)\r\n h2.person-name\r\n | #{person.firstname} #{person.lastname}\r\n a(href=`\/profile?id=${person.id}`)\r\n | View Profile\r\n<\/span><\/pre>\n
\nL\u1ed7i n\u00e0y c\u0169ng gi\u1ed1ng nh\u01b0 l\u00fac tr\u01b0\u1edbc t\u1ea5t c\u1ea3 ch\u00fang ta \u0111\u00e3 g\u1eb7p. \u0110\u01a1n gi\u1ea3n l\u00e0 server ch\u01b0a c\u00f3 thi\u1ebft l\u1eadp cho router \u201c \/ profile \u201d .<\/span>
\nT\u01b0\u01a1ng t\u1ef1 nh\u01b0 ph\u1ea7n thi\u1ebft l\u1eadp router cho trang ch\u1ee7, t\u1ea5t c\u1ea3 ch\u00fang ta li\u00ean t\u1ee5c v\u00e0o router cho ph\u1ea7n n\u00e0y nh\u01b0 sau :<\/span><\/p>\napp.get('\/profile', (req, res) => {\r\n const person = people.profiles.find(p => p.id === req.query.id);\r\n res.render('profile', {\r\n title: `About ${person.firstname} ${person.lastname}`,\r\n person,\r\n });\r\n});\r\n<\/span><\/pre>\n
extends default\r\n\r\nblock header\r\n\r\nblock content\r\n div.profile\r\n div.profile-image(style=`background: url('\/images\/${person.imgSrc}') top center\r\n no-repeat; background-size: cover;`)\r\n div.profile-details\r\n h1.profile-name\r\n | #{person.firstname} #{person.lastname}\r\n h2.profile-tagline\r\n | #{person.tagline}\r\n p.profile-bio\r\n | #{person.bio}\r\n a.button.button-twitter(href=`${person.twitter}`)\r\n | Follow me on Twitter\r\n<\/span><\/pre>\n
# T\u1ea1m k\u1ebft<\/span><\/h4>\n
\n\u0110\u1eebng qu\u00ean san s\u1ebb b\u00e0i vi\u1ebft \u0111\u1ec3 m\u1ecdi ng\u01b0\u1eddi c\u00f9ng h\u1ecdc nh\u00e9 .<\/span><\/p>\n
\nCategory: SEO Website<\/a><\/span><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"