Mình là dân lập trình và đầu tư cũng là mảng mình đang theo đuổi. Bài viết này với mục đích tổng hợp lại kiến thức và kinh nghiệm của mình liên quan tới NodeJs: Hướng dẫn cài đặt, thư viện hay dùng, xử lý lỗi và kinh nghiệm thực tế. Nó như bản lưu lại để tiện cho quá trình tra cứu tham khảo về sau.

NodeJS là một nền tảng được xây dựng trên V8 JavaScript Engine – trình thông dịch thực thi mã JavaScript, giúp xây dựng các ứng dụng web một cách đơn giản và dễ dàng mở rộng. NodeJS được phát triển bởi Ryan Dahl vào năm 2009 và có thể chạy trên nhiều hệ điều hành khác nhau: OS X, Microsoft Windows, Linux.
Theo khảo sát của Stack Overflow về các framework, nền tảng được sử dụng nhiều nhất năm 2019, NodeJS đã giành vị trí số 1 với số lượng người dùng lên đến gần 50%. Điều đó cho thấy nếu học NodeJS, cơ hội việc làm của bạn sẽ vô cùng rộng mở.
Nếu bạn muốn đi sâu lập trình NodeJs, bạn có thể tham khảo các cuốn sách sau:
- NodeJs in Practice
- NodeJs – Express In Action – Writing, building, and testing Node.js applications
- Node.js Application Developer’s Guide
Mục lục
Hướng dẫn cài đặt và sử dụng
Ngoài việc hướng dẫn cài đặt NodeJs, mình cũng hướng dẫn cài đặt NPM (Công cụ quản lý gói thư viện sử dụng trong NodeJs)và PM2 (Một tiện ích quản lý các process của NodeJs).
Cài đặt NodeJs
Trên Windows
Có nhiều cách cài đặt, ở đây mình giới thiệu 2 cách thông dụng nhất:
* Cài đặt thông qua NVM:
NVM (Node Version Manager) là tiện ích giúp quản lý nhiều phiên bản NodeJs trên 1 máy. Rất tiện lợi cho các máy của Developer vì trong quá trình lập trình, họ phải làm việc với nhiều project khác nhau, mỗi project khác nhau có thể sử dụng phiên bản NodeJs khác nhau. Với các DEV mình khuyến khích nên sử dụng theo cách này. Chi tiết xem tại: NVM là gì? Cài đặt nvm trên windows (Node.js)
Nói chung bạn chỉ việc vào địa chỉ https://github.com/coreybutler/nvm-windows/releases, tải bản mới nhất về cài đặt.
* Cài đặt trực tiếp:
Nếu ai không có như cầu sử dụng nhiều phiên bản, thì có thể dùng cách này. Tải trực tiếp phiên bản mới nhất trên Windows về để cài đặt: https://nodejs.org/en/download/
Trên Ubuntu
Có nhiều cách cài đặt, ở đây mình giới thiệu 2 cách thông dụng nhất:
* Cài đặt thông qua NVM:
NVM giúp quản lý nhiều phiên bản NodeJs trên máy nên khuyến khích DEV sử dụng theo cách này. Chi tiết xem: Hướng dẫn cài đặt nvm trên Ubuntu
Đầu tiên bạn tải NVM bằng lệnh:
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
Sau khi chạy sau lệnh trên, đoạn cuối có hướng dẫn yêu cầu chạy mấy lệnh để cấu hình (2 đến ba lệnh tùy phiên bản). Bạn chạy các lệnh này là xong nhé. Sau đó kiểm tra xem cài đặt okie chưa bằng lệnh:
nvm --version
Lệnh sử dụng NVM xem chi tiết: Sử dụng NVM
Ngoài NVM bạn có thể tham khảo thêm tiện ích tương tự: NodeNv
* Cài đặt trực tiếp:
Thường sử dụng để cài đặt trên server vì thường mỗi server chạy cho 1 project nào đó, gần như không có nhu cầu cài nhiều phiên bản. Mặt khác NVM quản lý các phiên bản NodeJs cho từng user, chứ không sử dụng chung cho các user được. Với server điều này là bất tiện vì thường user root sẽ cài tất cả các phần mềm cần thiết cho các user khác.
Lệnh cài đặt như dưới. Bạn có thể thay đổi phiên bản tùy theo yêu cầu.
Ví dụ cho phiên bản 8:
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install -y nodejs
Ví dụ cho phiên bản 14:
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - sudo apt-get install -y nodejs
Trên Ubuntu 22, nếu bạn cài mặc định bằng lệnh “sudo apt install nodejs” thì chỉ cài được bản v12.22.9. Muốn cài version cao hơn ví dụ v18.17.0, bạn dùng lệnh sau (Tham khảo: How To Install Node.js on Ubuntu 22.04):
cd ~
curl -sL https://deb.nodesource.com/setup_18.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh
sudo apt install nodejs
node -v
rm nodesource_setup.sh
Cách trên vẫn cài đặt okie nhưng gần đây có thông báo WARNING, vì thế bạn có thể cài đặt theo hướng dẫn chính thống từ nodesource-distributions. Tôi đóng gói lại thành tệp install-nodejs.sh như sau:
#!/bin/bash
# Update key
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
# Install Nodejs
NODE_MAJOR=$1
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
sudo apt-get update
sudo apt-get install nodejs -y
# Check NodeJs
node -v
Chạy lệnh sau để cài đặt:
# Cấp quyền thực thi chmod +x install-nodejs.sh # Cài đặt bản 18 ./install-nodejs.sh 18 # Cài đặt bản 16 ./install-nodejs.sh 16
Nếu cài bằng lệnh trên, bạn gỡ cài đặt bằng lệnh:
sudo -i
apt-get purge nodejs && rm -r /etc/apt/sources.list.d/nodesource.list && rm -r /etc/apt/keyrings/nodesource.gpg
Ghi chú: Trong một số trường hợp (Thường phiên bản cũ), sau khi cài đặt chỉ có file nodejs mà không có file node thì bạn dùng lệnh sau để tạo:
sudo ln -s /usr/bin/nodejs /usr/bin/node
Cài đặt NPM
NPM đã được tích hợp sẵn khi cài NodeJs nên bạn không cần phải cài đặt mà bạn chỉ cần biết cách sử dụng thôi. Bạn có thể check bằng lệnh:
npm -v
Sự dụng các lệnh NPM để cài đặt các gói. Tham khảo: An introduction to the npm package manager
Chi tiết các lệnh xem mục: Sử dụng NPM
Cài đặt PM2
PM2 là phần mềm quản lý các ứng dụng NodeJS (Advanced, production process manager for Node.js). Phần mềm này có nhiều tính năng, còn cho phép giám sát từ xa, nhưng đòi hỏi phải trả tiền. Nói chung, chúng ta chỉ cần dùng tính năng free của nó là đủ rồi.
Yêu cầu bạn phải cài NodeJS trước. Sau đó đánh lệnh sau để cài đặt:
sudo npm install pm2 -g
Sau khi hoàn thành thực hiện kiểm tra version:
pm2 -v
Chi tiết các lệnh xem mục: Sử dụng PM2
Hướng dẫn sử dụng
Sử dụng NVM
Sau khi cài đặt sau bạn sử dụng các lệnh của NVM để quản lý các phiên bản NodeJs. Các lệnh này giống nhau trên mọi hệ điều hành.
Cách lệnh hay dùng như sau:
// to list available remote versions of node (via nvm)
nvm ls-remote
// check version
node -v || node --version
// To list available remote versions on Windows 10 you can type
nvm list available
// list installed versions of node (via nvm)
nvm ls
// install specific version of node
nvm install 6.9.2
// set default version of node
nvm alias default 6.9.2
// switch version of node
nvm use 6.9.1
// uninstall specific version of node
nvm uninstall 6.9.2
Sử dụng NodeJs
Để start một ứng dụng trên NodeJs ta thường dùng lệnh sau:
node app.js
Đây là cách DEV hay dùng cho nhanh, nhưng có bất tiện mỗi khi sửa code liên quan tới ứng dụng thì bạn phải chạy lại lệnh này.
Trên NodeJs có thư viện nodemon, bạn chỉ cần chạy lệnh sau:
nodemon app.js
Mỗi khi tệp source code bất kỳ trong thư mục hiện tại hoặc các thư mục con thay đổi, nodemon sẽ tự động chạy lại ứng dụng. Chính bởi sự tiện lợi này mà thư viện nodemon được sử dụng rất nhiều.
Sử dụng npm
Các bạn đã dùng NodeJs chắc đều biết rõ cách lệnh này. Mình list lại các lệnh thông dụng, nhiều khi lâu không dùng có thể bị quên:
// list installed modules npm ls // install local package npm i <package> npm install <package> // install global package npm i -g <package> sudo npm install -g <package> // uninstall local package npm un <package> npm uninstall <package> sudo npm uninstall -g <package> // npm update packages npm up <package> npm update <package> // check package version => Return the lastest version npm view <package> version // Return all versions npm view <package> versions // Return current version of the package in local npm list <package> npm list -g <package> // Lệnh xóa cache và check lại cache // Hay dùng khi full HDD npm cache clean --force npm cache verify
Chi tiết bạn xem thêm tại: A Beginner’s Guide to npm, the Node Package Manager
Sử dụng PM2
Khi chạy ứng dụng NodeJs trên server hoặc VPS, thường sử dụng PM2 để tiện cho việc quản lý các ứng dụng Node. Dưới đây là danh sách các lệnh hay dùng trên PM2:
// Start the app pm2 start app.js // Start the app with name pm2 start app.js --name app_test // Start the app with name and arguments (Add any arguments after --) pm2 start app.js --name=app_test -- --type=checkdata // Monitoring apps pm2 monit // List apps pm2 list // Restart the app pm2 restart <id> pm2 restart <app_name> pm2 restart 0 pm2 restart app_test // Stop the app pm2 stop <id> pm2 stop <app_name> pm2 stop 0 pm2 stop app_test // Delete the app pm2 delete <id> pm2 delete <app_name> pm2 delete 0 pm2 delete
Đặc biệt, PM2 còn cho phép start nhiều process với nhiều tham số cấu hình hơn. PM2 không chỉ quản lý được ứng dụng nodejs mà có thể quản lý ứng dụng C/C++ (Qua Shell Script), các shell script,…
Ví dụ bạn tạo tệp apps.config.js với nội dung như sau:
module.exports = { apps : [ { name : 'app-01', cwd : './app_core/', script : 'PM2run.sh', args : 'app-01.ini', max_memory_restart : '200M', exec_intepreter : 'bash', exec_mode : 'fork_mode', autorestart : true, restart_delay : 3000 }, { name : "app-02", script : "./app.js", max_memory_restart : '2000M', autorestart : true, restart_delay : 3000 }, { name : "app-03", cwd : "./app_test/", script : "main.js", env: { "NODE_ENV": "app-03" }, autorestart : true, restart_delay : 3000 }, { name: 'app-04', script: "./main.js", cwd: "./gateway/", max_memory_restart: '2000M', autorestart: true, restart_delay: 1000, instance_var: 'INSTANCE_ID', env: { "NODE_ENV": "app-04" } } ] }
Khi đó bạn chỉ cần đánh lệnh sau:
pm2 start apps.config.js pm2 stop apps.config.js pm2 delete apps.config.js
Nói qua một số tham số cấu hình cho các process:
- name: Đặt tên cho process trên PM2
- cwd: Trong trường hợp bạn cần chuyển đến một thư mục nào đó trước khi start process thì mới cần khai báo tham số này.
- script: Lệnh thực hiện
- args: Tham số truyền vào
- max_memory_restart: Có thể không thiết lập. Khi được thiết lập, nếu RAM của process vượt quá giá trị này, PM2 sẽ tự động restart process này.
- exec_intepreter: Với ứng dụng NodeJs thì ko cần tham số này. Nhưng để chạy Shell Script sau thì phải sử dụng với giá trị bash.
- exec_mode: Với ứng dụng NodeJs thì không cần tham số này. Nhưng để chạy Shell Script sau thì phải sử dụng với giá trị fork_mode.
- autorestart: Nếu tham số này được thiết lập true, bất cứ khi nào ứng dụng chết (Do crash, exception, ai đó kill,…), PM2 sẽ tự động restart lại.
- restart_delay: Ứng dụng sẽ chờ thêm một khoảng thời gian trước khi restart lại.
- env: Thiết lập thêm biến môi trường
- instance_var: Xem thêm tại http://pm2.keymetrics.io/docs/usage/environment/
Các thư viện hay dùng trên NodeJs
Nếu bạn mới bắt đầu NodeJs bạn nên tham khảo trang Node.js Tutorial. Nó giúp bạn có sử dụng NodeJs cơ bản:
- Cách tạo và sử dụng module
- Biết cách sử dụng module cơ bản: HTTP Module, File System, URL Module, NPM, Events, Email, Upload Files
- Biết cách kết nối tới Database thông dụng như MySQL và MongoDB.
- Sử dụng NodeJs làm nhiều thứ với Raspberry Pi
Thư viện trên NodeJs rất là phong phú, hầu như bạn cần gì cũng có.
- Nhóm thư viện cơ bản:
- windows-build-tools: Thư viện cần phải cài đầu tiên khi bạn chạy NodeJs trên Windows. Vì nhiều thư viện trên NodeJs phải build, do đó cần cài đặt bộ công cụ này (Nhớ cài đặt ở quyền Administrator):
npm install –global windows-build-tools - underscore: Một thư viện chứa tất cả các hàm cơ bản hay được sử dụng nhất.
- bignumber.js: Thư viện thao tác với số lớn, hay dùng khi làm việc với Smart Contract. Cách dùng tham khảo: https://ethereumdev.io/how-to-deal-with-big-numbers-in-javascript/
- omit-empty: Là thư viện có nhiệm vụ chỉ lấy giá trị tồn tại và đồng thời có giá trị. Nó giúp bạn giảm thiểu phải check quá nhiều khi thao tác dữ liệu.
- p-queue: Khi bạn dùng Promise.all sẽ gặp vấn đề khi số lượng Promise quá nhiều. Khi đó thư viện p-queue là một giải pháp hiệu quả vì nó có cấu hình giúp bạn thiết lập số tác vụ đồng thời.
- bluebird: Bluebird là một thư viện hứa hẹn phổ biến cho JavaScript. Nó là một sự thay thế cho Promises gốc trong JavaScript.
- windows-build-tools: Thư viện cần phải cài đầu tiên khi bạn chạy NodeJs trên Windows. Vì nhiều thư viện trên NodeJs phải build, do đó cần cài đặt bộ công cụ này (Nhớ cài đặt ở quyền Administrator):
- Automation Testing: Một số cái dùng cho NodeJs, một số cái là nền tảng độc lập.
- Cypress: Được nhiều công ty sử dụng để kiểm thử tự động. Code bằng NodeJs
- Selenium: Selenium là bộ kiểm thử tự động miễn phí (mã nguồn mở) dành cho các ứng dụng web trên các trình duyệt và nền tảng khác nhau. Selenium không chỉ là 1 công cụ độc lập mà là 1 bộ công cụ của phần mềm, mỗi bộ đều đáp ứng được nhu cầu kiểm thử khác nhau của 1 tổ chức.
- Appium: Một công cụ kiểm thử tự động mã nguồn mở đa nền tảng. Appium được sử dụng để tự động hóa các test case cho các ứng dụng di động hybrid, native, mobile web. Công cụ này cho phép kiểm thử trên nhiều nền tảng như iOS, Windows và Android bằng cách sử dụng cùng một API.
- …
- Nhóm thư viện thao tác database:
- mongoose: Một thư viện cho phép ứng dụng NodeJs thao tác với database MongoDB theo mô hình hóa đối tượng (Object Data Model – ODM)
- PrismaClient: Một trình xây dựng truy vấn được tạo tự động cho phép truy cập cơ sở dữ liệu an toàn kiểu và giảm các bản soạn sẵn. Nó là một phần trong hệ sinh thái Prisma, cung cấp các công cụ cho các Dev làm việc với CSDL theo mô hình dữ liệu trực quan, an toàn.
- Nhóm thư viện Storage:
- local-storage: Thư viện giúp bạn lưu dữ liệu phía trình duyệt Browser. Nhưng nó bị giới hạn kích thước chỉ 5M dữ liệu.
- idb: Là thư viện gọn nhẹ giúp thao tác với IndexedDB. IndexedDB là CSDL lưu trữ ở phía client, trên trình duyệt của người sử dụng. IndexedDB là NoSQL Database, ngoài ra nó cũng hộ trợ các thao tác get, put và transactions. Với IndexedDB, bạn có thể lưu trữ được lượng dữ liệu lớn hơn.
- dexie: Cũng là một thư viện gọn nhẹ để thao tác với IndexedDB nhưng code đơn giản hơn, khản năng xử lý lỗi mạnh mẽ, khả năng mở rộng. Thấy dự án Ref Finance sử dụng thư viện này.
- Nhóm thư viện hỗ trợ parse dữ liệu, sinh dữ liệu, tạo tool tự đông:
- axios: Thư viện sử dụng rất nhiều với 14 triệu download hàng tuần. Mình sử dụng thư viện này khá nhiều và đã gặp vấn đề lỗi: “Thỉnh thoảng job bị dừng không thấy chạy tiếp” => Nguyên nhân là do axios mặc định không có timeout, nên trong một số trường hợp đặc biệt server bị lỗi không trả về response thì request cứ chờ mãi ở đó, làm job không chạy tiếp được => Nhớ sử dụng timeout cho các request. Mình đã gặp vấn đề này khi kết nối tới Binance API.
- Apollo Client: Thư viện hỗ trợ truy vấn GraphQL. Chi tiết xem tài liệu tại https://www.apollographql.com/docs/react/
- compression: Thư viện hỗ trợ nén response trả về => Nếu website của bạn chủ yếu trả về dữ liệu text thì thư viện giúp giúp cải tiến hiệu năng lên rất nhiều.
- node-html-parser: Một thư viện hỗ trợ parse HTML được sử dụng khá nhiều với hàng triệu download/tuần.
- cheerio: Dùng để tạo các trình thu thập dữ liệu. Thư viện thay thế: jsdom
- faker: Thư viện hỗ trợ tạo một lượng lớn dữ liệu giả trong trình duyệt và node.js. Tham khảo: https://viblo.asia/p/seeder-va-faker-de-tao-du-lieu-mau-cho-mongodb-nodejs-YWOZryANKQ0
- puppeteer: Thư viện NodeJs cung cấp API mức cao để thao tác với dữ liệu Web trên Chrome và Chromium. Rất hữu ích để tạo tool test ứng dụng web hoặc tạo công cụ tự động.
- Nhóm thư viện hỗ trợ quản lý Job:
- Agenda: Một thư viện nhỏ gọn để quản lý các job, giảm rất nhiều công sức nếu bạn tự quản lý job. Agenda sử dụng MongoDB làm CSDL. Nó còn hỗ trợ giao diện kiểm tra và quản lý job thông qua agendash. Một số vấn đề cần chú ý:
- Mặc dù thiết lập job 1 giây chạy 1 lần, nhưng thực tế thì 5s mới thấy job chạy 1 lần => Do mặc định agenda xử lý theo chu kỳ 5s (Xem: Agenda runs agenda.every(“0.1 seconds”, “job1”) every 5 seconds), để job có thể chạy với chu kỳ 1s thì khi khởi tạo cần thêm cấu hình processEvery:
let agenda = new Agenda( { processEvery: “1 seconds” }); - Mỗi lần restart lại ứng dụng, các job phải chờ mất 10 phút mới chạy lại => Đây cũng là một cấu hình mặc định của agenda, để giảm thời gian chờ đợi này bạn có thể sử dụng thệm lệnh:
agenda.defaultLockLifetime(5000);
- Mặc dù thiết lập job 1 giây chạy 1 lần, nhưng thực tế thì 5s mới thấy job chạy 1 lần => Do mặc định agenda xử lý theo chu kỳ 5s (Xem: Agenda runs agenda.every(“0.1 seconds”, “job1”) every 5 seconds), để job có thể chạy với chu kỳ 1s thì khi khởi tạo cần thêm cấu hình processEvery:
- Agenda: Một thư viện nhỏ gọn để quản lý các job, giảm rất nhiều công sức nếu bạn tự quản lý job. Agenda sử dụng MongoDB làm CSDL. Nó còn hỗ trợ giao diện kiểm tra và quản lý job thông qua agendash. Một số vấn đề cần chú ý:
- Nhóm thư viện với HTTP và Net:
- express: Thư viện HTTP server nhẹ, dễ dùng và được sử dụng rất nhiều. Có lựa chọn thay thế khác như: Koa, Hapi, Meteor
- express-rate-limit: Một middleware cho Express hỗ trợ giới hạn request trong một khoảng thời gian.
- socket.io: Thư viện hỗ trợ trao đổi dữ liệu hai chiều thời gian thực giữa client và server. Đây là thư viện được sử dụng khá nhiều.
- nodemailer: Thư viện hỗ trợ gửi email trên NodeJs. Lựa chọn thay thế: sendmail, emailjs
- morgan: Một thư viện middleware hỗ trợ lưu log các request HTTP. Thư viện thực sự rất hữu ích hỗ trợ nhiều trong việc debug ứng dụng web. Tham khảo: https://anonystick.com/blog-developer/3-middleware-huu-ich-khi-su-dung-express-rest-api-2019112318055877
- camelcase-keys: Một middleware hỗ trợ convert dữ liệu trên form trước khi tới backend.
- http-errors: Hỗ trợ tạo HTTP Error.
- Nhóm thư viện cho Unit Test:
- puppeteer: Thư viện NodeJs cung cấp API mức cao để thao tác với dữ liệu Web trên Chrome và Chromium. Rất hữu ích để tạo tool test ứng dụng web hoặc tạo công cụ tự động.
- faker: Thư viện hỗ trợ tạo một lượng lớn dữ liệu giả trong trình duyệt và node.js. Tham khảo: https://viblo.asia/p/seeder-va-faker-de-tao-du-lieu-mau-cho-mongodb-nodejs-YWOZryANKQ0
- jest: Là framework test hoàn chỉnh được phát triển và bảo trì bởi Facebook. Lượng download sử dụng hàng tuần khá lớn. Tham khảo các framework thay thế khác như: Jasmine, Ava và Mocha.
- Sinon: Là thư viện hỗ trợ unit test các hàm, nhiệm vụ chính của nó là hỗ trợ stub (thay thế các hàm) để hỗ trợ test tất cả các case nghiệp vụ mà không phải sửa đổi code. Khi sử dụng thư viện đôi khi gặp một số lỗi như dưới:
TypeError: stub(obj, ‘meth’, fn) has been removed, see documentation Do bản mới của Sinon thay đổi interface hàm, cần gọi theo cách mới. Chi tiết xem: https://sinonjs.org/releases/v2.4.1/migrating-to-2.0/ Còn không thì cài bản cũ (Version 1.x) - Mocha: Là framework hỗ trợ Unit Test được sử dụng khá rộng rãi, với nhiều hàm verify đầu ra hỗ trợ linh hoạt. Mocha kết hợp chai, supertest (HTTP assertion) và sinon là một lựa chọn hợp lý. Tham khảo: https://viblo.asia/p/unit-test-cho-nodejs-restful-api-voi-mocha-va-chai-bWrZnLAv5xw hoặc https://giaphiep.com/blog/unit-test-nodejs-project-with-mocha-chai-supertest-and-sinon-15067
NodeJs Full Stack
Là các bộ công cụ đầy đủ xây dựng ứng dụng NodeJs từ Backend, Frontend, Database được cấu hình từ NodeJs. Các bộ Full Stack hiện có gồm:
- MEAN Stack: Bộ công cụ gồm MongoDB, ExpressJS, AngularJS, Node.js. Tham khảo: https://www.mongodb.com/mean-stack
- MERN Stack: Bộ công cụ gồm MongoDB, ExpressJS, ReactJS, Node.js. Tham khảo: https://www.codeleaks.io/how-to-install-mern-stack-in-centos-redhat/
Việc dùng cái nào thì phụ thuộc bạn thành thạo Angular hay ReactJs hơn. Nếu bạn muốn biết chi tiết hơn sự khác nhau, hãy tham khảo: Difference between MEAN Stack and MERN Stack
Các frontend framework
Hầu hết các frontent framework đều là javascript nên xin liệt kê luôn vào đây. Có hai loại:
- Client Side Rendering (CSR): Các framework thực hiện render phía client.
- AngularJs và Angular 2+
- Ember.js
- Backbone.js: Một framework MVC Javascript.
- ReactJs
- Server-side Rendering (SSR):
Các công cụ hỗ trợ lập trình NodeJs
ESLint
Đang cập nhật…
Kinh nghiệm xây dựng ứng dụng NodeJs
Xây dựng một ứng dụng NodeJs đơn giản
Với người mới học NodeJs, các bạn nên xem bài viết: Xây dựng một ứng dụng NodeJS đơn giản với MongoDB. Công nghệ sử dụng gồm:
- NodeJS: Nodejs là một nền tảng (Platform) phát triển độc lập được xây dựng ở trên Javascript Runtime của Chrome mà chúng ta có thể xây dựng được các ứng dụng mạng một cách nhanh chóng và dễ dàng mở rộng.
- ExpressJS: Express js là một Framework nhỏ, nhưng linh hoạt được xây dựng trên nền tảng của Nodejs. Nó cung cấp các tính năng mạnh mẽ để phát triển web hoặc mobile
- EJS: Embedded JavaScript templating – Là một ngôn ngữ tạo mẫu đơn giản giúp bạn đánh dấu trang HTML bằng Javascript trong đó. Nó giúp chúng ta có thể quản lý view một cách dễ dàng và nhanh nhất.
- MongoDB: MongoDB là một trong những cơ sở dữ liệu mã nguồn mở NoSQL phổ biến nhất được viết bằng C++. MongoDB là cơ sở dữ liệu hướng tài liệu, nó lưu trữ dữ liệu trong các document dạng JSON với schema động rất linh hoạt. Nghĩa là bạn có thể lưu các bản ghi mà không cần lo lắng về cấu trúc dữ liệu như là số trường, kiểu của trường lưu trữ.
Với ứng dụng đơn giản loại này thì cấu trúc thư mục như sau là khá ổn:
.
├── db/
| ├── model/
| | └── product.js
| └── database.js
├── routes/
| └── controller.js
├── views/
| ├── add-product.ejs
| ├── home.ejs
| └── update-product.ejs
├── app.js
└── package.json
Triển khai một server đơn giản (Static server) trên NodeJs
Bạn có website đơn giản ở dạng HTML tĩnh hoặc site được build từ các ứng dụng ReactJs, NextJs. Site này muốn xem được phải triển khai trên một host server nào đó. Trong trường hợp này bạn có thể sử dụng NodeJs tạo ra một host server đơn giản chỉ với vài dòng lệnh.
Cách 1: Dùng thư viện node-static và http
Cách đầu tiên đơn giản nhất là ta sử dụng thư viện node-static và http. Code đơn giản như sau:
var http = require('http');
var nStatic = require('node-static');
var fileServer = new nStatic.Server('./public');
http.createServer(function (req, res) {
fileServer.serve(req, res);
}).listen(5000);
Mã html tĩnh bạn để hết trong thư mục public. Sau đó bạn chạy code trên, trên trình duyệt bạn vào link http://localhost:5000 để xem website.
Cách 2: Dùng thư viện express và serve-static
Nếu bạn quen dùng express thì bạn có thể sử dụng express và serve-static để tạo server. Code cũng đơn giản như sau:
var express = require('express');
var serveStatic = require('serve-static');
var app = express();
let port = 5000;
app.use(serveStatic('public', { index: ['index.html'] }))
app.listen(port);
console.log("The app listen on port:", port);
Tương tự như trên, các tệp html bạn đặt trong thư mục public, sau khi chạy code trên thi xem website tại địa chỉ: http://localhost:5000
Một số vấn đề gặp trong thực tế
Vấn đề Memory Leak trong NodeJS
Tham khảo:
- https://techmaster.vn/posts/33877/memory-leak-trong-nodejs
- https://dzone.com/articles/shallow-retained-and-deep-size
- https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them
Tạo heapdump để kiểm tra memory
Sử dụng thư viện heapdump để tạo dữ liệu: https://www.npmjs.com/package/heapdump
var heapdump = require('heapdump'); function writeHeadDump() { heapdump.writeSnapshot('./heapdump/heapdump_' + Date.now() + '.heapsnapshot'); } function cleanHeap() { // 1. Force garbage collection every time this function is called try { global.gc(); } catch (e) { console.log("You must run program with 'node --expose-gc index.js' or 'npm start'"); process.exit(); } // 2. Output Heap stats var heapUsed = process.memoryUsage().heapUsed; console.log("Program is using " + heapUsed + " bytes of Heap."); } // In dau tien o 5 phut dau tien setTimeout(function() { writeHeadDump(); }, 300000); // 1h in mot lan setInterval(function () { cleanHeap(); setTimeout(writeHeadDump, 5*1000); }, 3600*1000);
Để hàm cleanHeap chạy được khi start ứng dụng cần tham số “–expose-gc“
Memory tăng liên tục khi sử dụng MySQL Pool
Tôi gặp trường hợp sử dụng MySQL Pool từ thư viện: https://www.npmjs.com/package/mysql
Khi truy vấn database liên tục (Giao dịch nhiều), RAM của ứng dụng tăng nhanh và không bao giờ giảm, tức không bao giờ được giải phóng. Tương tự như báo lỗi tại link: https://github.com/mysqljs/mysql/issues/697
Nguyên nhân: Do Connection chưa hủy, nên nó cứ giữ các biến cache lại nhiều, và không thể giải phóng được.
Giải pháp: Hàng ngày vào giờ bảo gì phải tự động destroy các connection.
Ứng dụng quá tải khi tự quản lý Job
Nhiều người để nhanh thường sử dụng setInterval() để chạy các tác vụ liên tục (Gọi là các job), nếu tác vụ này thực hiện lâu thì rất dễ gây ra hiện tượng treo ứng dụng và có hiện tượng dữ liệu bị sai lệch.
Ví du: Bạn dùng setInterval() để thực hiện tác vụ A sau mỗi giây, nhưng tác vụ A phải thực hiện 10 phút. Như vậy trong vòng 10 phút tác vụ A được gọi 600 lần gây treo ứng dụng.
Trường hợp này nên sử dụng thư viện Agenda để quản lý job. Thư viện này sẽ đảm bảo rằng khi A thực hiện xong thì mới gọi tiếp.
SetOptionError: “useCreateIndex” is not a valid option to set
Khi sử dụng NodeJs thiết lập cấu hình như dưới cho Mongoose trong code:
mongoose.set('useCreateIndex', true);
Thì báo lỗi sau:
SetOptionError: useCreateIndex: "useCreateIndex" is not a valid option to set
at Mongoose.set (/home/ubuntu/git-data/dexscanner/collector/node_modules/mongoose/lib/index.js:250:17)
at Object.<anonymous> (/home/ubuntu/git-data/dexscanner/collector/utils/database/MongoDB.js:22:10)
Lỗi này do option useCreateIndex đã bị xóa từ Mongoose 6. Bỏ option này trong phiên bản mới.
Có hai cách sử lý lỗi này:
- C1: Nếu bạn muốn dùng thư viện mongo mới thì bỏ code sử dụng useCreateIndex() đi
- C2: Bạn lùi phiên bản của Mongoose về bản 5
npm rm mongoose
npm i mongoose@5.10.15
MongooseError: Model.findOne() no longer accepts a callback
Trong NodeJs sử dụng Mongoose code như dưới:
User.findOne({ email: email }, function( error, user ) {
// ...
})
Thì có thông báo lỗi:
MongooseError: Model.findOne() no longer accepts a callback
Do Mongoose không hỗ trợ callback từ phiên bản 5.0.
Có hai cách để xử lý:
- C1: Bạn sử dụng async/await thay cho callback
- C2: Bạn lùi phiên bản của Mongoose về bản 5
npm rm mongoose
npm i mongoose@5.10.15
Lỗi khi sử dụng Passport trên Nodejs: “Error: req#logout requires a callback function”
Trước đây khi sử dụng thư viện passport, ứng dụng vẫn chạy bình thường. Sau đó một thời gian cài đặt lại thư viện và chạy lại thì báo lỗi:
Error: req#logout requires a callback function
Nguyên nhân do thư viện passport từ phiên bản 0.6.0 đã chuyển req.logout() thành hàm bất đồng bộ và yêu cầu phải có callback trong. Chi tiết xem: Error: req#logout requires a callback function
Bạn phải sửa lại khi gọi hàm logout hoặc phải lùi passport về phiên bản từ 0.5.0 trở về trước. Lệnh như sau:
npm rm passport
npm i passport@0.4.1
Lỗi: FATAL ERROR- JS Allocation failed
Lỗi này phát sinh khi một ứng dụng NodeJs sử dụng bộ nhớ vượt qua giới hạn cho phép của mỗi ứng dụng NodeJs. Mặc định, giới hạn bộ nhớ trên NodeJs là 512MB, con số này có thể thay đổi tùy từng phiên bản.
Nếu ứng dụng bạn gặp lỗi này thì bạn phải tăng giới hạn bộ nhớ cho NodeJs sử dụng tham số “–max-old-space-size“. Ví dụ:
node --max-old-space-size=1024 server.js # increase to 1gb
node --max-old-space-size=2048 server.js # increase to 2gb
node --max-old-space-size=3072 server.js # increase to 3gb
node --max-old-space-size=4096 server.js # increase to 4gb
node --max-old-space-size=5120 server.js # increase to 5gb
node --max-old-space-size=6144 server.js # increase to 6gb
node --max-old-space-size=7168 server.js # increase to 7gb
node --max-old-space-size=8192 server.js # increase to 8gb
Chi tiết hơn, hãy xem bài viết: [TIPS] Increase memory limit in Node.js
Có thể bạn quan tâm: Kiến thức lập trình
Nguồn: Sưu tầm
2 Pingbacks