--------------- <> -----------------
--- KHOA HỌC - CÔNG NGHỆ - GIÁO DỤC - VIỆC LÀM ---
--- Học để đi cùng bà con trên thế giới ---

Tìm kiếm trong Blog

Web back-end (7) - Local và Global, Dependencies và devDependencies

Bài trước: Web back-end (6) - Cấu hình Web server trong Nodejs
-----
7. Local và Global, Dependencies và devDependencies
7.1 Local và Global

Ở các phần trước chúng ta đã trải nghiệm với việc sử dụng công cụ NPM để cài đặt framework, các công cụ (gọi chung là các gói), cũng đã làm quen với khái niệm cài đặt cục bộ (local), toàn cục (global) trong môi trường Nodejs.

Phần này chúng ta sẽ cùng tìm hiểu kĩ hơn về các khái niệm trên, đồng thời rút ra được kinh nghiệm trong việc lựa chọn kiểu cài đặt cho phù hợp.

Ngoài ra, thực hành nhiều sẽ giúp bạn có kỹ năng tốt, dễ nhớ và dễ hiểu về công nghệ.

Để thực hành, chúng ta sẽ tạo mới một ứng dụng (ví dụ kieu-cai-dat):

- Trong ổ đĩa E:\, tạo thư mục có tên kieu-cai-dat

- Mở cửa sổ dòng lệnh, di chuyển dấu nhắc chuột tới kieu-cai-dat

- Dùng lệnh npm init -y để tạo tập tin package.json cho ứng dụng

E:\kieu-cai-dat>npm init -y

Wrote to E:\kieu-cai-dat\package.json:

{

  "name": "kieu-cai-dat",

  "version": "1.0.0",

  "main": "index.js",

  "scripts": {

    "test": "echo \"Error: no test specified\" && exit 1"

  },

  "keywords": [],

  "author": "",

  "license": "ISC",

  "description": ""

}

Chúng ta đã tạo ra được tập tin package.json trong thư mục dự án. Tập tin package.json sẽ ghi lại thông tin của các gói được cài đặt theo kiểu cục bộ.

Dấu hiệu để nhận ra một gói được cài theo kiểu cục bộ là thông tin của gói sẽ được lưu trong package.json.

Do chúng ta chưa cài bất kỳ gói nào cho dự án (kieu-cai-dat) theo kiểu cục bộ, nên package.json chưa có thông tin gì về gói cục bộ.

[package.json]

{

  "name": "kieu-cai-dat",

  "version": "1.0.0",

  "main": "index.js",

  "scripts": {

    "test": "echo \"Error: no test specified\" && exit 1"

  },

  "keywords": [],

  "author": "",

  "license": "ISC",

  "description": ""

}

Cài đặt một gói kiểu cục bộ

Một gói cục bộ sẽ được cài đặt bằng lệnh npm theo cú pháp sau:

npm install <package_name>

Ví dụ, chúng ta sẽ cài đặt gói Express theo kiểu cục bộ vào dự án kieu-cai-dat

E:\kieu-cai-dat>npm install express

added 69 packages, and audited 70 packages in 9s

14 packages are looking for funding

  run `npm fund` for details

found 0 vulnerabilities

Một gói được cài đặt theo kiểu cục bộ, thì bạn chỉ có thể sử dụng ở trong phạm vi của dự án. Như vậy, bạn chỉ có thể sử dụng gói Express trong dự án kieu-cai-dat, nếu bạn tạo một dự án khác (ví dụ kieu-cai-dat-2) thì dự án mới tạo sẽ không sử dụng được gói Express trong dự án kieu-cai-dat.

Chúng ta sẽ lấy phạm vi thư mục dự án (kieu-cai-dat) làm giới hạn để xác định giữa cục bộ và toàn cục. Cái gì nằm trong dự án thì gọi là cục bộ, nằm ngoài dự án thì gọi là toàn cục.

Do Express được cài đặt theo kiểu cục bộ, nên thông tin về gói này sẽ được ghi lại trong tập tin package.json, mục dependencies:

[package.json]

 "description": "",

  "dependencies": {

    "express": "^4.21.2"

  }

Vị trí lưu trữ gói cục bộ

Khi một gói được cài đặt theo kiểu cục bộ, mã nguồn của gói sẽ được lưu trong dự án (kieu-cai-dat), tại thư mục node_modules.


Mỗi khi dự án có sử dụng các gói cục bộ, Nodejs sẽ tìm kiếm gói tương ứng trong thư mục node_modules.

Nội dung thư mục node_modules sẽ thay đổi khi bạn thực hiện lệnh cài đặt/gỡ bỏ gói bằng lệnh npm.

Gỡ bỏ một gói cục bộ

Để gỡ bỏ gói Express, sử dụng lệnh:

npm uninstall <package_name>

Ví dụ:

E:\kieu-cai-dat>npm uninstall express

removed 69 packages, and audited 1 package in 1s

found 0 vulnerabilities

Sau khi gỡ bỏ gói Express, mục dependencies trong package.json cũng được cập nhật lại.

Cài đặt một gói kiểu toàn cục (global)

Để cài đặt một gói kiểu toàn cục, sử dụng lệnh npm install có thêm tham số -g

npm install <package_name> -g

Tham số (hay cờ) -g là viết tắt của global.

Ví dụ, chúng ta sẽ cài đặt gói nodemon theo kiểu toàn cục.

E:\kieu-cai-dat>npm install nodemon -g

changed 29 packages in 4s

4 packages are looking for funding

  run `npm fund` for details

Mặc dù đã cài đặt thành công nodemon, nhưng vào kiểm tra trong tập tin package.json, sẽ không thấy có thông tin được cập nhật. Vì chỉ có cài gói theo kiểu cục bộ thì mới được cập nhật vào package.json.

Vị trí lưu trữ gói toàn cục

Sau khi cài đặt thành công, để biết được gói toàn cục được lưu ở đâu trong máy tính, sử dụng lệnh sau:

npm root -g

Ví dụ:

E:\kieu-cai-dat>npm root -g

C:\Users\Teo\AppData\Roaming\npm\node_modules

Theo đường dẫn C:\Users\Teo\AppData\Roaming\npm\node_modules, bạn sẽ thấy được gói nodemon.

Để xem các gói đã được cài đặt theo kiểu toàn cục trên máy tính, sử dụng lệnh sau:

npm ls -g --depth 0

Ví dụ:

E:\kieu-cai-dat>npm ls -g --depth 0

C:\Users\Teo\AppData\Roaming\npm

+-- nodemon@3.1.9

`-- pnpm@10.4.1

Trong đó,

- npm ls: để liệt kê các gói đã được cài đặt trên máy, ls là viết tắt của list

- -g là cờ báo, để chỉ hiển thị các gói kiểu toàn cục (global)

-  --depth 0: chỉ hiển thị các gói toàn cục cấp cao nhất (top-level), không hiển thị các gói là con-cháu (sub-dependencies) của gói cấp cao nhất

Nên cài đặt gói theo kiểu cục bộ hay toàn cục

Trong quá trình phát triển ứng dụng web, việc quyết định cài đặt một gói là cục bộ hay toàn cục phụ thuộc vào mục đích sử dụng của gói đó và cách bạn muốn tích hợp nó vào ứng dụng hoặc hệ thống của mình.

Các trường hợp nên cài gói cục bộ:

- Khi gói chỉ cần thiết cho một dự án cụ thể và không cần sử dụng ở phạm vi rộng hơn

- Khi bạn muốn các phụ thuộc (dependencies) của dự án được quản lý chặt chẽ trong tập tin package.json, giúp dễ dàng tái tạo môi trường phát triển ở máy khác (ví dụ: khi chia sẻ mã nguồn hoặc triển khai)

- Khi gói là một phần của ứng dụng hoặc thư viện mà bạn đang phát triển (ví dụ: express)

Các trường hợp nên cài gói toàn cục:

- Khi gói là công cụ dòng lệnh (CLI) hoặc tiện ích mà bạn muốn sử dụng ở bất kỳ đâu trong hệ thống, không phụ thuộc vào dự án cụ thể (ví dụ: nodemon)

- Khi bạn cần chạy gói như một lệnh độc lập từ cửa sổ dòng lệnh mà không cần viết script trong package.json

Một số lưu ý

[1] Ưu tiên cài cục bộ khi có thể: ngay cả với các công cụ dòng lệnh như eslint hay prettier, bạn vẫn có thể cài cục bộ và chạy chúng thông qua script trong package.json. Điều này giúp đảm bảo mọi thành viên trong nhóm hoặc môi trường CI/CD sử dụng cùng phiên bản. Ví dụ: thay vì cài nodemon toàn cục, bạn có thể cài cục bộ và chạy npx nodemon app.js.

[2] Khi nào cần cả hai? Đôi khi bạn muốn cài toàn cục để tiện sử dụng cá nhân, nhưng vẫn cài cục bộ cho dự án để đảm bảo tính nhất quán. Ví dụ: bạn cài typescript toàn cục để chạy lệnh tsc nhanh chóng, nhưng vẫn thêm nó vào devDependencies của dự án.

[3] Tránh lạm dụng cài toàn cục: chỉ nên cài toàn cục cho các công cụ thực sự cần thiết ở phạm vi hệ thống. Việc cài quá nhiều gói toàn cục có thể dẫn đến khó quản lý và xung đột phiên bản.

7.2 Dependencies và devDependencies

Nhắc lại, chỉ có các gói được cài đặt theo kiểu cục bộ (trong dự án), thì mới được cập nhật thông tin trong package.json, trong mục dependencies và devDependencies.

Như vậy, dependencies và devDependencies là hai phần trong tập tin package.json, dùng để quản lý các gói mà dự án của bạn phụ thuộc vào. Sự khác biệt giữa chúng nằm ở mục đích sử dụng và giai đoạn mà chúng được yêu cầu trong vòng đời của dự án.

Các gói nằm trong mục dependencies

- Là các gói cần thiết để ứng dụng của bạn chạy trơn tru trong môi trường sản xuất, triển khai (production). Đây là những phụ thuộc "cốt lõi" mà mã nguồn của bạn trực tiếp sử dụng để hoạt động.

- Là một phần không thể thiếu trong xử lý logic của ứng dụng, ví dụ: framework express, thư viện xử lý HTTP, truy vấn cơ sở dữ liệu

- Khi người khác cài đặt dự án của bạn bằng lệnh npm install, các gói trong dependencies sẽ được tải về, vì chúng cần thiết để chạy ứng dụng

Ví dụ:

 "dependencies": {

    "express": "^4.21.2"

  }

Cách cài đặt một gói là dependencies

Sử dụng lệnh sau:

npm install <package-name> --save

Lưu ý: từ npm phiên bản 5 trở lên, --save là mặc định, nên bạn chỉ cần dùng lệnh sau:

npm install <package-name>

Các gói nằm trong mục devDependencies

- Là các gói chỉ cần thiết trong quá trình phát triển ứng dụng (development) hoặc kiểm thử (testing), không cần thiết khi ứng dụng chạy ở môi trường sản xuất, triển khai (production)

- Khi gói là công cụ hỗ trợ lập trình viên, như công cụ kiểm tra cú pháp (linter), trình biên dịch (transpiler), framework kiểm thử (testing framework), hoặc công cụ khởi động server trong lúc thử nghiệm (nodemon)

- Khi cài đặt ứng dụng lên môi trường triển khai (production), các gói trong devDependencies sẽ không được cài đặt, giúp giảm dung lượng và tăng hiệu suất

Ví dụ:

"devDependencies": {

  "nodemon": "^3.0.1",

}

Cách cài đặt một gói là devDependencies

Sử dụng lệnh sau:

npm install <package-name> --save-dev

7.3 Bài tập

Bài tập 7.1 Thực hiện các cài đặt trong bài học.

Câu 7.2 Trong môi trường phát triển ứng dụng Nodejs, phát biểu nào không đúng khi nói về gói cục bộ?

A. Gói cục bộ được cài đặt trong thư mục node_modules của dự án

B. Gói cục bộ chỉ có thể được sử dụng trong dự án mà nó được cài đặt

C. Gói cục bộ được quản lý thông qua file package.json và có thể sử dụng các phiên bản khác nhau giữa các dự án

D. Gói cục bộ luôn được cài đặt toàn cục trên hệ thống để tất cả các dự án đều có thể truy cập

Câu 7.3 Trong môi trường phát triển ứng dụng Nodejs, phát biểu nào không đúng khi nói về gói toàn cục?

A. Gói toàn cục luôn được liệt kê trong tập tin package.json của dự án

B. Gói toàn cục thường được sử dụng cho các công cụ dòng lệnh (CLI) như nodemon

C. Gói toàn cục được lưu trong thư mục toàn cục của hệ thống và có thể truy cập từ bất kỳ dự án nào

D. Gói toàn cục được cài đặt bằng lệnh npm install -g <package-name>

Câu 7.4 Trong môi trường phát triển ứng dụng Nodejs, phát biểu nào không đúng khi nói về kiểu cài đặt dependencies?

A. Các gói trong dependencies được cài đặt cục bộ trong dự án bằng lệnh npm install <package-name>

B. Các gói trong dependencies là các phụ thuộc cần thiết để ứng dụng chạy trong môi trường triển khai, sản xuất (production)

C. Các gói trong dependencies chỉ được sử dụng trong giai đoạn phát triển và không cần thiết khi triển khai ứng dụng (production)

D. Các gói trong dependencies được liệt kê trong tập tin package.json và tự động cài đặt khi chạy npm install

Câu 7.5 Trong môi trường phát triển ứng dụng Nodejs, phát biểu nào không đúng khi nói về kiểu cài đặt devDependencies?

A. Các gói trong devDependencies được cài đặt bằng lệnh npm install <package-name> --save-dev

B. Các gói trong devDependencies là các phụ thuộc cốt lõi để ứng dụng chạy trong môi trường triển khai (production)

C. Các gói trong devDependencies chỉ cần thiết trong giai đoạn phát triển hoặc kiểm thử, không cần cho môi trường triển khai (production)

D. Các gói trong devDependencies không được cài đặt khi chạy npm install --production

-----
Bài sau: Web back-end (8) - Một số chủ đề JavaScript (1)

Web back-end (6) - Cấu hình Web server trong Nodejs

Bài trước: Web back-end (5) - Nodejs và NPM
-----
6. Cấu hình Web server trong Nodejs
6.1 Package.json

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:

http://localhost:9000

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

-----