Thử tưởng tượng, ngày đầu bạn đi tới trường đại học, khi tới cổng trường, sẽ rất hữu ích nếu bạn có một “sổ tay trường đại học”.
Trong cuốn sổ tay này có thông tin mô tả về trường, hướng dẫn đường đi, giới thiệu về các tòa nhà, chỉ dẫn các tiện ích về thư viện, căn tin, phòng học.
Trong một ứng dụng viết trên Nodejs, tập tin package.json cũng đóng vai trò như một cuốn sổ tay, là “sổ tay ứng dụng”, cũng có thể gọi là “hồ sơ ứng dụng” (manifest).
Tập tin package.json chứa một số thông tin sau:
- Thông tin mô tả về ứng dụng
- Quản lý các phụ thuộc (quản lý các thư viện sử dụng trong ứng dụng)
- Các lệnh chạy (scripts), định nghĩa ngắn gọn các lệnh để điều khiển ứng dụng
- Đầu vào (entry point, main) của dự án, cho biết tập tin đầu tiên được triệu gọi
Dùng NPM để tạo tập tin package.json
Ở phần trước, chúng ta đã cài đặt NPM.
Phần này, chúng ta sẽ sử dụng NPM để tạo ra tập tin package.json cho dự án web.
Nếu đang sử dụng hệ điều hành Windows, bạn có thể sử dụng công cụ dòng lệnh bất kỳ để thao tác với NPM. Ví dụ: CMD, Command Prompt, Bash, PowerShell.
Bạn cũng có thể sử dụng tiện ích Terminal của VS Code. Thực tế, tiện ích Terminal sẽ gọi các chương trình dòng lệnh của Windows để thực thi (ví dụ PowerShell).
- Mở chương trình dòng lệnh (Terminal trên VS Code)
- Di chuyển dấu nhắc lệnh vào thư mục dự án (ví dụ TeoShop).
[Vài lệnh quan trọng: cd để đi vào thư mục con, cd .. để đi lên thư mục cha, C: để vào ổ đĩa C:\; ls hoặc dir để xem nội dung thư mục. Chương trình dòng lệnh không phân biệt hoa/thường nên gõ tên thư mục hoa/thường là như nhau]
- Chạy lệnh: npm init -y
- Nếu chạy thành công, kết quả xuất ra màn hình sẽ là:
PS E:\teoshop> npm init -y
Wrote to E:\teoshop\package.json:
{
"name": "teoshop",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
[Lỗi liên quan đến PowerShell
- Khi chạy lệnh npm init -y trong PowerShell, bạn có thể gặp lỗi phân quyền như sau:
PS E:\teoshop> npm init -y
npm : File C:\Program Files\nodejs\npm.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at
https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:1
+ npm init -y
+ ~~~
+ FullyQualifiedErrorId : UnauthorizedAccess
- Để sửa lỗi: mở menu Start của Windows, gõ PowerShell vào cửa sổ tìm kiếm, bấm chuột phải vào PowerShell > chọn Run as Administrator > sau đó gõ lệnh Set-ExecutionPolicy
RemoteSigned > bấm Enter > nhập A > Enter.
- Ví dụ:
PS C:\Windows\system32> Set-ExecutionPolicy RemoteSigned
Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose you to the security risks described in the about_Execution_Policies
help topic at https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): A ]
Lệnh npm init -y
Lệnh npm init -y được sử dụng để khởi tạo một dự án Node.js mới với file package.json mà không cần phải trả lời các câu hỏi cấu hình thủ công.
Thông thường, khi bạn chạy npm init mà không có tham số -y, npm sẽ hiển thị một loạt câu hỏi tương tác (như tên dự án, phiên bản, mô tả, tác giả) để bạn nhập thông tin chi tiết. Tuy nhiên, khi thêm tùy chọn -y (viết tắt của "yes"), npm sẽ tự động điền các giá trị mặc định cho tất cả các câu hỏi này và tạo ngay tập tin package.json mà không yêu cầu sự can thiệp của bạn.
Chữ init là viết
tắt của initialize (khởi tạo).
Sau khi thực hiện thành công lệnh npm init -y; tập tin package.json trong dự án (TeoShop) có nội dung như sau:
[package.json]
{
"name": "teoshop",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo
\"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
Từ tập tin package.json, biết được:
- Tên dự án: teoshop
- Tập tin tiếp theo được gọi để thực thi là index.js
6.2 Cài đặt PNPM, Express, Web server, Nodemon
Để cài đặt web server trong môi trường Nodejs, chúng ta sẽ sử dụng framework Express.
Để cài đặt Express, có thể sử dụng lệnh npm, hoặc pnpm.
Chúng ta sẽ sử dụng pnpm (Performant Node Package Manager) để cài đặt Express, vì dùng pnpm giúp bạn tiết kiệm không gian đĩa cứng hơn so với dùng npm.
Vào website: https://pnpm.io/ để đọc thêm về pnpm.
Trước khi có thể sử dụng pnpm, chúng ta phải cài đặt công cụ này.
Sử dụng npm để cài đặt pnpm.
Cài đặt PNPM
Vào chương trình dòng lệnh, gõ lệnh sau:
E:\TeoShop>npm install -g pnpm@latest-10
added 1 package in 8s
1 package is looking for funding
run `npm fund` for details
Trong đó:
- npm install: lệnh của npm, dùng để cài đặt các gói, thư viện, công cụ
- g: tham số global (cài đặt ở phạm vi toàn cục)
- pnpm: tên công cụ cần cài đặt
- @latest-10: phiên bản mới nhất của bản 10-x
Sau khi cài đặt pnpm, sử dụng lệnh pnpm -v để kiểm tra xem pnpm đã cài đặt thành công chưa? Nếu có thông tin về phiên bản là đã cài đặt thành công.
E:\TeoShop>pnpm -v
10.4.1
Ở đây, có câu hỏi đặt ra là: mặc dù dùng lệnh pnpm -v sẽ kiểm tra được pnpm đã cài đặt thành công hay chưa? Nhưng, nếu thành công rồi thì chương trình được lưu ở đâu trên đĩa cứng? Bạn hãy đặt câu hỏi này cho chatbot để tìm hiểu thêm.
Để biết vị trí lưu trữ tập tin thực thi, bạn có thể sử dụng lệnh (trên Windows): where ten-tap-tin :
D:\Demos\TeoShop>where pnpm
C:\Users\VIET HOANG - VTS\AppData\Roaming\npm\pnpm
C:\Users\VIET HOANG - VTS\AppData\Roaming\npm\pnpm.cmd
Kết quả lệnh của lệnh where pnpm cho thấy máy tính đã tìm thấy 2 tập thực thi tại cùng một vị trí. Đây là cách Windows quản lý các lệnh thực thi toàn cục (global) được cài đặt qua npm.
Đường dẫn C:\Users\VIET HOANG - VTS\AppData\Roaming\npm\ là thư mục lưu trữ mặc định cho các gói cài đặt toàn cục của Node.js (global node modules).
- Tập tin pnpm (không có đuôi): Thực chất là một đoạn mã Shell script dành cho các terminal như Git Bash hoặc WSL trên Windows
- Tập tin pnpm.cmd: Đây mới là tập tin cho phép bạn gõ lệnh pnpm trực tiếp vào Command Prompt (CMD) hoặc PowerShell. Khi bạn gõ pnpm -v, thực tế Windows đang chạy tệp .cmd này
Quá trình npm cài đặt pnpm (cài theo chế độ global) gồm các bước sau:
- npm chép mã nguồn của pnpm đang vào C:\Users\VIET HOANG - VTS\AppData\Roaming\npm\node_modules
- Tạo một tập tin thực thi pnpm.cmd tại Roaming\npm
- Thêm đường dẫn của tập tin thực thi pnpm.cmd vào biến môi trường PATH của Windows. Thực tế: quá trình cài đặt pnpm thường không tự thêm đường dẫn vào PATH ở mỗi lần cài. Thay vào đó, đường dẫn C:\Users\...\AppData\Roaming\npm đã được Node.js/npm thêm sẵn vào PATH ngay từ khi bạn cài đặt Node.js lên máy tính. Vì đường dẫn thư mục cha đã nằm trong PATH, nên bất kỳ tập tin .cmd nào bạn bỏ vào đó (như pnpm.cmd, nodemon.cmd, yarn.cmd) đều sẽ chạy được ngay lập tức.
Câu hỏi tiếp theo đặt ra là: tại sao cài đặt các gói bằng pnpm lại tiết kiệm không gian lưu trữ trên đĩa cứng?
Pnpm tiết kiệm không gian đĩa cứng nhờ và 3 lý do sau:
- [1] Cơ chế “Kho lưu trữ duy nhất” (Single Content-addressable Store). Ở các công cụ khác (như npm), nếu bạn có 100 dự án cùng sử dụng thư viện lodash, bạn sẽ có 100 bản sao của lodash nằm trong 100 thư mục node_modules.
Với pnpm:
- Tất cả các gói (packages) chỉ được tải về và lưu duy nhất một lần tại một thư mục trung tâm trên ổ cứng (thường là trong %AppData%/pnpm/store trên Windows)
- Khi bạn cài đặt gói đó cho dự án thứ 2, 3...v.v pnpm sẽ không tải lại mà chỉ lấy từ kho này ra
- [2] Sử dụng Liên kết cứng (Hard Links): Thay vì sao chép mã nguồn từ kho lưu trữ vào thư mục node_modules của dự án, pnpm tạo ra một Hard link. Nó giống như việc một tệp tin vật lý nhưng có thể xuất hiện ở nhiều đường dẫn khác nhau. Dù bạn thấy thư viện nằm trong D:\Project\node_modules, nhưng thực chất nó không chiếm thêm bất kỳ byte nào trên đĩa cứng vì nó dùng chung vùng dữ liệu với tệp trong kho lưu trữ trung tâm
- [3] Tiết kiệm ngay cả với các phiên bản khác nhau. pnpm không chỉ tiết kiệm giữa các gói giống hệt nhau, mà còn giữa các phiên bản khác nhau của cùng một gói. Nếu lodash phiên bản 4.1.0 và 4.1.1 chỉ khác nhau một vài dòng mã ở 1 tập tin, pnpm sẽ chỉ lưu thêm đúng tập tin khác biệt đó. Những tập tin giống nhau giữa hai phiên bản sẽ được dùng chung.
Cài đặt framework Express
Trong giao diện dòng lệnh, di chuyển dấu nhắc chuột vào thư mục dự án (TeoShop), gõ lệnh sau để cài đặt framework Express:
E:\TeoShop>pnpm i -s express
Trong đó:
- i có nghĩa là cài đặt (install)
- s là viết tắt của --save, với tùy chọn này, thông tin của Express sẽ được thêm vào phần dependencies trong package.json, thư viện Express sẽ được lưu trong thư mục node_modules của dự án.
Sau khi cài được Express, mở tập tin package.json, sẽ thấy thông tin của Express được lưu trong phần dependencies.
…
"license": "ISC",
"description": "",
"dependencies": {
"express": "^4.21.2"
}
Trong thư mục dự án (TeoShop) cũng xuất hiện thêm thư mục node_modules. Thư mục node_modules này dùng để lưu trữ các gói mà dự án sẽ sử dụng. Như vậy, Express cũng được lưu trong node_modules.
Tạo tập tin index.js
Như trong package.json có khai báo, tập tin mã nguồn đầu tiên được gọi và thực thi (đầu vào của ứng dụng) là index.js.
Trong thư mục dự án (TeoShop), chúng ta sẽ tạo tập tin index.js.
Trong tập tin index.js, khai báo để tạo web server.
[index.js]
'use strict'
const express = require('express')
const app = express();
const port =
process.env.PORT || 9000
// xu ly khi nguoi dung gui request toi web server
app.get("/", (req, res) => {
res.send('Chao ban den voi TeoShop!!');
})
// khoi dong web server
app.listen(port, () => {
console.log(`server dang chay tren cong ${port}`);
})
Vào cửa sổ dòng lệnh để khởi chạy web server vừa được tạo. Sử dụng lệnh sau:
node index.js
Nếu web server chạy được, sẽ có thông báo là:
PS E:\TeoShop> node index.js
server dang chay tren cong 9000
Để tắt web server, chuyển dấu nhắc chuột vào cửa sổ dòng lệnh, dùng tổ hợp phím Ctrl + C.
Lỗi khi chạy trong Terminal (VS Code)
Chạy lệnh node trong Terminal (VS Code) có thể bị lỗi sau:
PS E:\TeoShop> node -v
node : The term 'node' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling
of the name, or if a path was included, verify that the path is
correct and try again.
At line:1 char:1
+ node -v
+ ~~~~
+ CategoryInfo
: ObjectNotFound: (node:String) [], CommandNotFoundException
+ FullyQualifiedErrorId :
CommandNotFoundException
Lỗi trên do công cụ Terminal của VS Code không nhận được biến môi trường của lệnh node.
Cách sửa: vào chương trình VS Code, bấm tổ hợp phím Ctrl + Shift + P > nhập Select Default Profile > chọn Command Prompt.
Khi web server đang chạy, mở cửa sổ trình duyệt, nhập đường dẫn:
Bạn sẽ thấy dòng chữ:
Chao ban den voi TeoShop!
Vậy là bạn đã cài đặt, và chạy được web server trên môi trường Nodejs.
6.3 Cài đặt Nodemon
Trong quá trình làm việc với web server, mỗi lần thay đổi mã nguồn của tập tin (index.js), chúng ta đều phải tắt web server (Ctrl + C), và chạy lại. Mục đích để web server cập nhật lại mã nguồn. Điều này khá bất tiện.
Chúng ta sẽ cài đặt công cụ Nodemon để tự khởi động lại web server mỗi khi cập nhập mã nguồn.
Đọc thêm về Nodemon ở đây: https://www.npmjs.com/package/nodemon
Chúng ta sẽ cài Nodemon ở chế độ global để có thể sử dụng trong nhiều dự án khác.
Để cài đặt Nodemon, vào cửa sổ dòng lệnh, gõ lệnh:
npm install --g nodemon
Ví dụ:
E:\TeoShop>npm install --g nodemon
added 29 packages in 4s
4 packages are looking for funding
run `npm fund` for details
Sử dụng Nodemon
Sau khi cài đặt Nodemon > mở chương trình dòng lệnh > chuyển dấu nhắc lệnh vào thư mục dự án > gõ lệnh nodemon.
Tiện ích Nodemon sẽ khởi chạy web server.
Bạn sửa mã nguồn trong tập tin index.js > lưu lại tập tin > Nodemon sẽ tự khởi động lại web server > bạn vào lại trình duyệt > làm mới lại (refresh) trang web để xem kết quả > bạn sẽ thấy những cập nhật trong tập tin index.js đã được cập nhật trên trình duyệt.
6.4 Bài tập
Bài tập 6.1 Thực hiện các cài đặt, cấu hình trong bài học.
Bài tập 6.2 Làm sao biết được một gói cài đặt ở chế độ cục bộ (locally) hay toàn cục (globally)? Khi cài đặt các gói (package) ở chế độ cục bộ và toàn cục (globally) thì các gói sẽ được lưu ở đâu? Làm sao bạn biết được?
Bài tập 6.3 Sự khác nhau khi cài đặt gói ở chế độ dependencies và devDependencies?
Câu 6.4 Trong ứng dụng chạy trên nền Nodejs, tập tin package.json dùng để làm gì? Phát biểu nào không đúng?
A. Chứa thông tin mô tả về ứng dụng
B. Quản lý các phụ thuộc
C. Chỉ ra tập tin JavaScript đầu tiên được thực thi
D. Chứa mã để tạo giao diện ứng dụng
Câu 6.5 PNPM là gì? Phát biểu nào không đúng?
A. Giúp tiết kiệm dung lượng đĩa
B. Có thể thay thế hoặc bổ sung cho NPM
C. Là viết tắt của Performant Node Package Manager
D. Không thể thay thế hoặc bổ sung cho NPM
Câu 6.6 Express trong Node.js được sử dụng để làm gì?
A. Tạo ứng dụng web và API
B. Quản lý cơ sở dữ liệu
C. Thiết kế giao diện người dùng
D. Kiểm tra hiệu suất ứng dụng
Câu 6.7 Nodemon
trong Node.js được sử dụng để làm gì?
A. Kết nối với cơ sở dữ liệu
B. Tạo giao diện người dùng cho ứng dụng
C. Quản lý các gói phụ thuộc
D. Tự động khởi động lại server khi mã thay đổi