Hai bài trước chúng ta đã cùng khám phá những ưu điểm của Node.js. Các bạn cảm thấy háo hức để bắt đầu khám phá thế giới của Node.js chưa? Để bắt đầu hành trình lập trình Node.js, chúng ta sẽ tự tay xây dựng một ứng dụng web đơn giản bằng Node.js và Express.js.
Trước khi bắt tay vào viết code, mình sẽ điểm qua những thư viện, công cụ được sử dụng trong bài viết đã nhé.
Express js là gì?
ExpressJS là một framework web được xây dựng dựa trên nền tảng NodeJs, tập trung vào việc cung cấp các công cụ và middleware để tạo ra các API đơn giản và dễ sử dụng.
Với việc được phát hành dưới giấy phép mã nguồn mở và được hỗ trợ bởi một cộng đồng lớn, ExpressJS là lựa chọn lý tưởng cho các ứng dụng thương mại. Người dùng hoàn toàn có thể tin tưởng và sử dụng framework này cho mọi loại dự án, từ nhỏ đến lớn.
Cấu trúc thư mục của một dự án sử dụng ExpressJS thường bao gồm ba phần chính: routes, Views và Public. Framework này tuân theo mô hình MVC (Model – View – Controller) trong việc xây dựng ứng dụng web.
Một số chức năng chính của ExpressJS:
- Hỗ trợ middleware để trả về các HTTP request
- Định nghĩa route dựa trên các action của HTTP (CRUD)
- Cho phép trả về các trang html sử dụng các template engine (jade, pug…)
Để tạo ứng dụng web với NodeJS cần những gì?
Nếu bạn đã quen thuộc với JavaScript nhưng kiến thức của bạn chủ yếu xoay quanh việc phát triển ứng dụng front-end, bài viết này sẽ phù hợp với bạn.
Trong cộng đồng lập trình, JavaScript được xem là một trong những ngôn ngữ linh hoạt nhất cho đến thời điểm hiện tại. Với JavaScript, bạn có thể xây dựng ứng dụng từ phía front-end đến phía back-end, từ ứng dụng di động đến các ứng dụng web.
Trước khi bắt đầu, điều quan trọng là bạn cần cài đặt Node.js và NPM.
Hãy chắc chắn bạn đã cài đặt thành công Node.js và NPM bằng cách kiểm tra vesion của chúng bằng terminal:
- node -v
- npm -v
Mình tin là với các phiên bản Node.js và NPM cũ hơn thì bạn vẫn có thể code tốt được. Tuy nhiên, nếu có bất kì lỗi xảy khi làm theo bài viết của mình việc đầu tiên bạn nghĩ tới là nâng cấp version của Nodejs và NPM nhé!
Giới thiệu ứng dụng web với NodeJS sẽ xây dựng trong bài viết
Chúng ta sẽ hợp tác xây dựng một ứng dụng web đơn giản sử dụng Node.js và ExpressJS nhằm giúp các bạn mới tiếp xúc với công nghệ này không cảm thấy quá khó khăn. Ứng dụng sẽ bao gồm Trang chủ và một số trang con.
Chúng ta sẽ sử dụng Express.js và thư viện PUG (trước đây là Jade) để render HTML cho ứng dụng này.
Đây là giao diện ứng dụng web sau khi hoàn thành bài viết.
Khởi tạo ứng dụng
Các bạn có thể sử dụng lệnh của NPM để tạo một dự án mới tinh. Đơn giản là gõ lệnh sau và làm theo hướng dẫn:
- npm init
Nếu lười, bạn có thể download dự án mình tạo sẵn tại đây:
Sau khi tải về, bạn mở cửa sổ terminal và chuyển đến thư mục dự án, gõ lệnh sau để cài đặt toàn bộ thư viện( dependencies) cần thiết:
- npm install
Các bạn mở file server.js lên và import và khởi tạo express.js như bên dưới:
- const express = require(‘express’);
- const app = express();
Hàm express()
là hàm cao nhất được exported bởi express module
Tiếp theo, chúng ta sẽ tạo một server để chạy website. Như của mình thì server sẽ chạy trên port 7000, bạn có thể đổi port sang bất kì port nào cũng được.
- const server = app.listen(7000, () => {
- console.log(`Express running → PORT ${server.address().port}`);
- });
Chúng ta thử start server lên xem thế nào. Từ terminal, bạn gõ lệnh sau:
- node server.js
Khi server đã khởi động thành công, bạn vào trình duyệt và truy cập vào địa chỉ: http://localhost:7000
. Bạn sẽ trình duyệt báo lỗi: “Cannot GET /“. Lỗi này xảy ra vì bạn chưa định nghĩa bất kì router cho website cả. Chưa có thì giờ mình tạo thôi.
Để định nghĩa một router GET bằng expressJS, bạn sử dụng đoạn code sau:
- app.get(‘/’, (req, res) => {
- res.send(‘Hello World!’);
- });
Đoạn code trên có nghĩa là, khi bạn truy cập vào trang chủ( địa chỉ “/”) qua phương thức GET, server sẽ trả về một message là “” Hello World”.
Lưu ý: Mặc dù bạn có thể tạo router cho bất kì loại request nào của HTTP như POST, PUT, DELETE. Tuy nhiên, bài viết này mình chỉ sử dụng phương phức GET cho đơn giản.
OK, sau khi thiết lập router xong, bạn khởi động lại server để thay đổi code có hiệu lực. Kết quả thu được như sau:
Sử dụng pm2 để tự khởi động server khi thay đổi code
Như bạn có thể thấy, mỗi khi bạn chỉnh sửa mã, bạn phải khởi động lại máy chủ để các thay đổi có hiệu lực.
Để tiết kiệm thời gian phát triển ứng dụng, có thể sử dụng các công cụ tự động khởi động lại máy chủ khi mã thay đổi. Có nhiều công cụ như nodemon, forever, PM2… Tùy thuộc vào sở thích, tôi thích sử dụng PM2 vì tính hiệu quả của nó.
Nếu bạn kiểm tra file package.json, bạn sẽ thấy tôi đã đặt PM2 trong devDependencies, vì vậy bạn có thể sử dụng PM2 mà không cần cài đặt thêm.
Bạn tạo một script trong package.json như sau:
- {
- // …
- “scripts”: {
- “start”: “npx pm2 start server.js –watch”
- }
- // …
- }
Cuối cùng, bạn chạy lại server bằng lệnh:
- npm start
Từ bây giờ trở đi, bạn cứ thay đổi code thoải mái là có thể test được ngay mà không cần phải khởi động lại server nữa. Quá tiện phải không?
>> Đọc thêm: Tự xây dựng RESTful APIs với Nodejs
#Rendering HTML sử dụng Pug
Thường khi người dùng truy cập vào một URL của trang web, máy chủ sẽ phản hồi bằng một trang HTML cụ thể. Thay vì chỉ trực tiếp trả về một tập tin HTML đã được tạo sẵn, chúng ta thường sử dụng các công cụ như template engine để hỗ trợ tạo ra các trang HTML.
Một template engine cho phép chúng ta xây dựng một mẫu trang HTML và sau đó thay thế các biến trong mẫu đó bằng các giá trị cụ thể trước khi gửi trang về cho người dùng. Nếu bạn đã từng làm việc với data binding trong lập trình Android, bạn có thể nắm được cách mà template engine hoạt động, với việc liên kết dữ liệu tương tự.
Có một số template engine có thể làm việc với ExpressJS như: Pug(Jade), EJS, Mustache…
Trong bài viết này, mình sẽ sử dụng Pug, đơn giản vì mình đã quen cách sử dụng của nó. Các bạn sau này có thể tùy ý lựa chọn cho dự án của mình.
Để sử dụng Pug, chúng ta cần khai báo trong package.json
- “dependencies”: {
- “pug”: “^2.0.3”
- },
Và khai báo trong server.js
- app.set(‘view engine’, ‘pug’);
Trong ExpressJS, các template HTML sẽ được đặt trong thư mục Views. Trong ví dụ này, mình thử tạo một file template có tên là: index.pug có nội dung như sau:
- p Hello Pug!
Để render ra file template này khi người dùng vào trang chủ, ta sửa đoạn thiết lập router ở trên thành:
- app.get(‘/’, (req, res) => {
- res.render(‘index’)
- });
Và kết quả thu được như sau:
Note: Để sử dụng PUG, chúng ta cần biết một vài syntax của nó. Tuy nhiên, do bài viết này hơi dài nên mình sẽ hướng dẫn các bạn cách sử dụng PUG ở một bài viết khác nhé. Các bạn nhớ đón đọc nhé!
Xây dựng giao diện và logic của ứng dụng web
Đọc đến đây thì bạn đã có một số kiến thức cơ bản về ExpressJS, template engine. Chúng ta sẽ bắt tay vào xây dựng trang web như ở đầu bài viết đã trình bày.
Đầu tiên, chúng ta sẽ tạo giao diện trang chủ, đặt tên là default.pug, code sẽ như sau:
- doctype html
- html
- head
- title #{title}
- link(rel=’stylesheet’, href=’/css/style.css’)
- meta(name=”viewport” content=”width=device-width, initial-scale=1″)
- body
- main
- block header
- header.header
- h1 #{title}
- block content
Từ khóa block giống như include trong layout android vậy. Nghĩa là chúng ta có thể chèn một file template khác vào. Điều này giúp chúng ta tái sử dụng template tốt hơn.
Còn đây là file index.pug
- extends default
- block content
- div.container
Chúng ta lại sửa lại đoạn code thiết lập router ở trên thành như sau:
- app.get(‘/’, (req, res) => {
- res.render(‘index’, {
- title: ‘Homepage’
- });});
Như ở đây, tất cả biến #{title}
trong file default.pug sẽ được thay thế bằng text: “Homepage” rồi trả về cho trình duyệt. Kết quả như sau:
Làm việc với static content
Trên đây, chúng ta mới chỉ trả về mỗi HTML cho trình duyệt. Để trang web đẹp hơn, chúng ta cần phải có CSS.
Để sử dụng được CSS trong ExpressJS, chúng ta thêm đoạn code sau:
- // …
- app.set(‘view engine’, ‘pug’);
- // serve static files from the `public` folder
- app.use(express.static(__dirname + ‘/public’));
- // …
Xong, bạn thử refesh lại trình duyệt và tận hưởng kết quả:
Làm việc với JSON data trong NodeJS
Các website bây giờ đa phần là web động, tức là server sẽ lưu dữ liệu trong database, rồi lại lấy ra đưa lên các template engine.
Vì chúng ta không sử dụng database trong bài viết này, nên mình sẽ tạo một file JSON vậy.
Mình sẽ tạo file people.json có cấu trúc như sau:
- {
- “profiles”: [
- {
- “firstname”: “Duong”,
- “lastname”: “Anh Sơn”,
- “bio”:
- “Anh Sơn là một lập trình Android và giờ đang hướng dẫn về NodeJS.”,
- “tagline”: “Developer, Writer and Speaker”,
- “twitter”: “https://twitter.com/ngotuannghia”,
- “imgSrc”: “tom-jagger.jpg”,
- “id”: “tom”
- },
- ]
- }
Đại khái như vậy, các bạn tự đổi nội dung theo ý mình nhé!
Chúng ta khai báo file JSON trong server.js. Và kết quả server.js sẽ như sau:
- const express = require(‘express’);
- const people = require(‘./people.json’);
- const app = express();
- app.set(‘view engine’, ‘pug’);
- app.use(express.static(__dirname + ‘/public’));
- app.get(‘/’, (req, res) => {
- res.render(‘index’, {
- title: ‘Homepage’,
- people: people.profiles
- });
- });
- const server = app.listen(7000, () => {
- console.log(`Express running → PORT ${server.address().port}`);
- });
Như đoạn code trên, chúng ta reference file JSON vào biến people. Sau đó pass mảng profiles vào template engine thông qua people.
Bây giờ, bạn đổi một chút ở index.pug như sau:
- extends default
- block content
- div.container
- each person in people
- div.person
- div.person-image(style=`background: url(‘/images/${person.imgSrc}’) top center
- no-repeat; background-size: cover;`)
- h2.person-name
- | #{person.firstname} #{person.lastname}
- a(href=`/profile?id=${person.id}`)
- | View Profile
Kết quả thu được:
Khi bạn thử click vào link: “View Profile” ngay lập tức bạn sẽ bị lỗi “cannot GET /profile“.
Lỗi này cũng giống như lúc trước chúng ta đã gặp. Đơn giản là server chưa có thiết lập cho router “/profile”.
Tương tự như phần thiết lập router cho trang chủ, chúng ta tiếp tục vào router cho phần này như sau:
- app.get(‘/profile’, (req, res) => {
- const person = people.profiles.find(p => p.id === req.query.id);
- res.render(‘profile’, {
- title: `About ${person.firstname} ${person.lastname}`,
- person,
- });
- });
và template engine thì tạo một file mới: profile.pug
- extends default
- block header
- block content
- div.profile
- div.profile-image(style=`background: url(‘/images/${person.imgSrc}’) top center
- no-repeat; background-size: cover;`)
- div.profile-details
- h1.profile-name
- | #{person.firstname} #{person.lastname}
- h2.profile-tagline
- | #{person.tagline}
- p.profile-bio
- | #{person.bio}
- a.button.button-twitter(href=`${person.twitter}`)
- | Follow me on Twitter
Thế là xong. Giờ chúng ta thử refesh trình duyệt và click vào từng profile xem kết quả nhé
Tạm kết
Thông qua bài viết này, tôi đã hướng dẫn cách tạo ứng dụng web đơn giản bằng NodeJS và ExpressJS. Ban đầu, khi mới tiếp xúc với NodeJS, bạn có thể cảm thấy lạ lẫm. Tuy nhiên, khi bạn quen thuộc hơn, bạn sẽ nhận ra sức mạnh của nó.
Tôi hy vọng rằng bạn sẽ tìm thấy bài viết này hữu ích. Nếu bạn ủng hộ, tôi sẽ tiếp tục chia sẻ kiến thức về NodeJS để chúng ta cùng tiến xa hơn trong học tập.
Đừng quên chia sẻ bài viết để mọi người cùng nhận được kiến thức này.