Node.js được xây dựng dựa trên JavaScript runtime. Nghe thật tuyệt, nhưng bạn đã thật sự hiểu chi tiết Node.js là gì? Nó hoạt động như thế nào? Cùng TopDev tìm hiểu từ A-Z về NodeJS trong bài viết dưới đây!
Node.js là gì?
NodeJS là một nền tảng được xây dựng trên “V8 Javascript engine” được viết bằng c++ và Javascript. Nền tảng này được phát triển bởi Ryan Lienhart Dahl vào năm 2009.
Node.js là một môi trường thực thi JavaScript nguồn mở và đa nền tảng.
Ghi chú: Trong quá trình nghiên cứu tìm hiểu về Node.js, bạn sẽ bắt gặp rất nhiều cách viết khác như nodejs, nodeJS hay node js, các cách viết này đều được hiểu là đang nói về Node.js.
Node.js ra đời khi các developer đời đầu của JavaScript mở rộng nó từ một thứ bạn chỉ chạy được trên trình duyệt thành một thứ bạn có thể chạy trên máy của mình dưới dạng ứng dụng độc lập.
- Nguồn mở (Open-source): Mã nguồn của Node.js được công bố công khai, điều này có nghĩa là bất kỳ ai cũng có thể truy cập, sử dụng, và đóng góp vào mã nguồn. Node.js được duy trì bởi cộng đồng lập trình viên trên toàn thế giới, và hướng dẫn đóng góp của Node.js hướng dẫn bạn cách để bạn có thể góp phần phát triển nó.
- Đa nền tảng (Cross-platform): Node.js không phụ thuộc vào bất kỳ hệ điều hành nào cụ thể nào, nghĩa là nó có thể chạy trên Linux, macOS hoặc Windows. Điều này làm cho Node.js trở thành một lựa chọn linh hoạt cho các nhà phát triển muốn xây dựng các ứng dụng có thể hoạt động trên nhiều nền tảng khác nhau mà không cần thay đổi mã nguồn.
- Môi trường thực thi JavaScript (JavaScript runtime environment): Để mã JavaScript có thể được thực thi, nó cần một môi trường chạy phù hợp. Trong khi trình duyệt như Chrome và Firefox cung cấp một môi trường thực thi cho JavaScript, Node.js mở rộng khả năng này ra ngoài trình duyệt. Node.js cho phép chạy JavaScript trên máy chủ, hoặc trong bất kỳ môi trường máy tính nào khác, không chỉ trong trình duyệt.
- Dựa trên V8 JavaScript Engine: Node.js được xây dựng dựa trên V8, động cơ JavaScript được phát triển bởi Google cho trình duyệt Chrome. Điều này giúp Node.js có khả năng thực thi JavaScript nhanh và hiệu quả, đồng thời hỗ trợ các tính năng mới nhất của ngôn ngữ JavaScript.
Node.js đã mở rộng khả năng của JavaScript từ việc chỉ phát triển front-end trong trình duyệt để bao gồm cả phát triển back-end. Điều này có nghĩa là các lập trình viên có thể sử dụng cùng một ngôn ngữ lập trình, JavaScript, để phát triển toàn bộ ứng dụng, từ front-end đến back-end, qua đó tạo điều kiện cho việc học tập và phát triển ứng dụng nhanh chóng và hiệu quả hơn.
JavaScript giờ có khả năng làm những thứ và những ngôn ngữ lập trình scripting như Python có thể làm.
Xem việc làm Node.js tại đây
Nodejs hoạt động ra sao?
Node.js hoạt động dựa trên một số nguyên tắc cơ bản giúp nó hiệu quả trong việc xử lý các ứng dụng có nhiều hoạt động nhập/xuất (I/O) mà không bị chặn, đồng thời giảm đáng kể sự phức tạp trong quản lý các luồng thực thi. Dưới đây là một số thành phần chính giải thích cách thức hoạt động của Node.js:
Kiến trúc Non-blocking I/O và Event-Driven:
Node.js sử dụng một mô hình non-blocking I/O (input/output) và event-driven, nghĩa là các hoạt động như đọc file, truy vấn cơ sở dữ liệu, hoặc giao tiếp mạng được thực hiện mà không chặn tiến trình chính. Điều này cho phép xử lý nhiều yêu cầu cùng lúc mà không cần tạo nhiều luồng (thread), giúp giảm bớt chi phí liên quan đến quản lý luồng và tối ưu hóa hiệu suất.
Khi một hoạt động I/O được khởi tạo, nó sẽ được gửi đến thực thi trong hệ thống hoặc cơ sở dữ liệu mà không làm chậm tiến trình chính. Sau khi hoạt động hoàn tất, một sự kiện sẽ được phát đi và xử lý bằng các hàm gọi lại (callback).
V8 JavaScript Engine
Node.js được xây dựng trên động cơ JavaScript V8 của Google Chrome, đây là một động cơ rất nhanh cho phép biên dịch mã JavaScript thành mã máy để thực thi trực tiếp trên phần cứng, làm tăng hiệu suất thực thi.
Single-Threaded
Mặc dù Node.js hoạt động trên một luồng duy nhất cho logic ứng dụng của người dùng, nó vẫn sử dụng nhiều luồng ở tầng thấp hơn thông qua thư viện libuv
để xử lý các hoạt động I/O. Tuy nhiên, những chi tiết này được ẩn giấu khỏi người dùng, giúp việc lập trình đơn giản hơn mà vẫn đảm bảo hiệu suất.
Event Loop
Trái tim của Node.js là “event loop”. Đây là vòng lặp sự kiện mà ở đó Node.js tiếp tục lắng nghe sự kiện và thực hiện các hàm gọi lại khi một sự kiện được kích hoạt. Vòng lặp sự kiện cho phép Node.js xử lý hàng nghìn kết nối đồng thời mà không cần phải tạo ra chi phí quản lý luồng.
Trigger Callback
Khi thao tác I/O hoàn tất, hệ điều hành thông báo cho Node.js, và Node.js sau đó thực thi hàm callback tương ứng để xử lý kết quả hoặc tiếp tục xử lý logic.
NPM (Node Package Manager)
NPM là hệ thống quản lý gói cho Node.js, cho phép các nhà phát triển dễ dàng chia sẻ và sử dụng mã nguồn từ nhau. NPM là một trong những kho lưu trữ mã nguồn mở lớn nhất thế giới và chứa hàng ngàn module có thể được tích hợp vào ứng dụng của bạn.
Tổng hợp lại, Node.js mang đến một mô hình hiệu quả và mạnh mẽ cho các ứng dụng web và máy chủ, nhờ khả năng xử lý đồng thời nhiều hoạt động I/O mà không bị chặn, và qua đó tối ưu hóa việc sử dụng tài nguyên và cải thiện hiệu suất.
Require
Require làm 3 thứ:
- Tải module đi kèm với Node.js như hệ thống file và HTTP từ Node.js API.
- Tải thư viện thứ 3 như Express và Mongoose mà bạn cài đặt từ npm.
- Giúp bạn require file của bạn và mo-đun hoá project.
Require là 1 chức năng, và nó nhận tham số path tinh chỉnh và trả về module.export
.
Thành phần của Node.js
Bây giờ, chúng ta hãy cùng tìm hiểu từng phần của Node.js để hiểu rõ hơn về nền tảng phía máy chủ nói chung.
Module
Module giống như thư viện JavaScript có thể được sử dụng trong ứng dụng Node.js để bao gồm một tập hợp các hàm. Để bao gồm một module trong ứng dụng Node.js, hãy sử dụng hàm require() với dấu ngoặc đơn chứa tên của module.
const http = require("http");
Tham khảo một số Node.js Module:
Console
Console là một module cung cấp phương pháp gỡ lỗi tương tự như console JavaScript cơ bản do trình duyệt internet cung cấp. Nó in thông báo ra stdout và stderr.
console.log('hello world')
Cluster
Node.js được xây dựng dựa trên khái niệm lập trình đơn luồng. Cluster là một mô-đun cho phép đa luồng bằng cách tạo các tiến trình con chia sẻ cùng một cổng máy chủ và chạy đồng thời.
Có thể thêm cụm vào ứng dụng theo cách sau:
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length; // Get the number of CPU cores
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers for each CPU
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died`);
console.log('Forking a new worker');
cluster.fork(); // Fork a new worker if one dies
});
} else {
// Workers can share any TCP connection
// In this case, it is an HTTP server
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello Worldn');
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
Global
Các đối tượng toàn cục trong Node.js có sẵn trong tất cả các mô-đun. Các đối tượng này là hàm, mô-đun, chuỗi, v.v. Một số đối tượng toàn cục của Node.js được đề cập trong bảng dưới đây:
Đối tượng toàn cục | Mô tả |
---|---|
global | Đối tượng toàn cục chung, tương tự như window trong trình duyệt. |
process | Cung cấp thông tin và điều khiển về quá trình thực thi Node.js. |
console | Cung cấp các phương thức để ghi log thông tin, lỗi và các thông báo khác. |
Buffer | Lớp toàn cục giúp làm việc với các dữ liệu nhị phân (binary data). |
setTimeout | Lên lịch thực thi một hàm sau một khoảng thời gian nhất định. |
clearTimeout | Hủy một hàm đã được lên lịch bởi setTimeout . |
setInterval | Lên lịch thực thi một hàm nhiều lần, với khoảng thời gian cố định giữa các lần thực thi. |
clearInterval | Hủy một hàm đã được lên lịch bởi setInterval . |
setImmediate | Thực thi một hàm ngay lập tức sau khi vòng lặp sự kiện hiện tại kết thúc. |
clearImmediate | Hủy một hàm đã được lên lịch bởi setImmediate . |
__dirname | Chứa đường dẫn tới thư mục của tệp hiện tại. |
__filename | Chứa đường dẫn tuyệt đối tới tệp hiện tại. |
module | Đối tượng liên quan đến mô-đun hiện tại, chứa thông tin về mô-đun. |
require() | Hàm dùng để nhập các mô-đun khác vào tệp hiện tại. |
Luồng (Streaming)
Luồng là các đối tượng cho phép bạn đọc dữ liệu hoặc ghi dữ liệu liên tục. Có bốn loại luồng:
- Có thể đọc được: Đây là loại luồng mà dữ liệu có thể được đọc
- Có thể ghi: Đây là loại luồng mà dữ liệu có thể được ghi vào
- Duplex: Đây là cả luồng có thể đọc và ghi
- Chuyển đổi: Các luồng có thể thao tác dữ liệu trong khi nó đang được đọc hoặc ghi
Đệm (Butter)
Buffer là một module cho phép xử lý các luồng chỉ chứa dữ liệu nhị phân. Một bộ đệm rỗng có chiều dài ’10’ có thể được tạo bằng phương pháp này:
var buf = Butter.alloc(10)
Miền (Domain)
Mô-đun miền chặn các lỗi vẫn chưa được xử lý. Có hai phương pháp được sử dụng để chặn các lỗi này:
- Liên kết nội bộ: Trình phát lỗi thực thi mã của nó bên trong phương thức chạy
- Liên kết bên ngoài: Bộ phát lỗi được thêm rõ ràng vào miền thông qua phương thức add của nó
DNS
Mô-đun DNS được sử dụng để kết nối với máy chủ DNS và thực hiện phân giải tên bằng phương pháp sau:
dns.resolve()
Mô-đun DNS cũng được sử dụng để thực hiện phân giải tên mà không cần kết nối mạng bằng cách sử dụng phương pháp sau:
dns.lookup()
Trình gỡ lỗi
Node.js bao gồm một tiện ích gỡ lỗi có thể được truy cập bằng một trình gỡ lỗi tích hợp. Trình gỡ lỗi Node.js không có nhiều tính năng nhưng hỗ trợ kiểm tra mã đơn giản. Trình gỡ lỗi có thể được sử dụng trong thiết bị đầu cuối bằng cách sử dụng từ khóa ‘inspect’ trước tên tệp JavaScript. Để kiểm tra tệp — ví dụ: myscript.js—bạn có thể làm theo phương pháp này:
$ node inspect myscript.js
Tại sao nên sử dụng Node.js?
Dưới đây là một số lý do chính tại sao nhiều lập trình viên lại ưu tiên lựa chọn Node.js:
- Hiệu suất cao: Node.js được xây dựng trên động cơ JavaScript V8 của Google Chrome, cho phép biên dịch mã JavaScript thành mã máy nhanh chóng. Nhờ đó, thời gian thực thi của Node.js rất nhanh, làm tăng hiệu suất của các ứng dụng.
- Hệ sinh thái phong phú: Với hơn 50,000 gói có sẵn trong Node Package Manager (NPM), các nhà phát triển có thể dễ dàng tìm và sử dụng các thư viện theo nhu cầu của họ mà không cần phải viết lại từ đầu, tiết kiệm đáng kể thời gian và công sức.
- Xử lý bất đồng bộ và không chặn (Asynchronous and Non-blocking): Node.js hoạt động một cách bất đồng bộ và không chặn các hoạt động I/O, nghĩa là nó không cần chờ đợi API trả về dữ liệu trước khi tiếp tục xử lý yêu cầu tiếp theo. Điều này làm cho Node.js trở nên lý tưởng cho việc xây dựng các ứng dụng web thời gian thực và xử lý dữ liệu lớn.
- Tính nhất quán trong mã nguồn: Node.js cho phép sử dụng cùng một ngôn ngữ lập trình (JavaScript) cho cả phía máy chủ và máy khách. Điều này không chỉ giúp giảm thiểu sự không đồng bộ giữa client và server mà còn làm cho việc bảo trì và quản lý mã nguồn trở nên dễ dàng hơn.
- Khả năng mở rộng: Node.js hỗ trợ xây dựng các ứng dụng có khả năng mở rộng cao thông qua mô hình sự kiện và bất đồng bộ của mình. Điều này cho phép xử lý hàng ngàn kết nối đồng thời mà không làm giảm hiệu suất.
- Ngôn ngữ quen thuộc: Vì Node.js là một khung làm việc JavaScript, nó trở thành lựa chọn lý tưởng cho những nhà phát triển đã quen thuộc với JavaScript. Điều này làm cho quá trình học tập và phát triển dự án với Node.js trở nên dễ dàng hơn nhiều.
Nhờ những đặc điểm này, Node.js đã trở thành một trong những lựa chọn hàng đầu cho việc phát triển phía máy chủ, đặc biệt là trong các dự án yêu cầu hiệu suất cao và khả năng xử lý đồng thời lớn.
Ứng dụng của NodeJS
Node.js được sử dụng rộng rãi trong nhiều loại ứng dụng web và server do khả năng xử lý bất đồng bộ, hiệu suất cao, và hệ sinh thái phong phú của nó. Dưới đây là một số ứng dụng phổ biến của Node.js
- Ứng dụng Web Thời Gian Thực (Real-time Web Applications): Node.js là lựa chọn lý tưởng cho các ứng dụng web thời gian thực như trò chuyện trực tuyến và trò chơi trực tuyến do khả năng xử lý các sự kiện I/O một cách nhanh chóng và hiệu quả.
- APIs Server-side: Node.js thường được sử dụng để xây dựng RESTful APIs do khả năng xử lý đồng thời lớn và tốc độ phản hồi nhanh, làm cơ sở cho các ứng dụng di động và web.
- Streaming Data: Node.js hỗ trợ xử lý dữ liệu dạng stream, cho phép ứng dụng xử lý các tệp video, âm thanh hoặc các dữ liệu khác trong khi chúng vẫn đang được truyền, thay vì phải chờ cho đến khi toàn bộ tệp được tải về.
- Ứng dụng Một Trang (Single Page Applications): Node.js phù hợp với việc phát triển các ứng dụng một trang (SPA) như Gmail, Google Maps, hay Facebook, nơi mà nhiều tương tác xảy ra trên một trang duy nhất mà không cần tải lại trang.
- Công cụ và Tự Động Hóa: Node.js cũng được sử dụng để phát triển các công cụ dòng lệnh và các script tự động hóa quy trình làm việc, nhờ vào các gói NPM hỗ trợ đa dạng và khả năng tích hợp dễ dàng với các công nghệ khác.
- Microservices Architecture: Node.js là một lựa chọn phổ biến cho kiến trúc microservices, nơi các ứng dụng lớn được chia thành các dịch vụ nhỏ, độc lập và dễ quản lý hơn.
- Ứng dụng IoT (Internet of Things): Node.js thường được sử dụng trong các ứng dụng IoT, nơi cần xử lý một lượng lớn các kết nối đồng thời và các sự kiện từ các thiết bị IoT.
- Dashboard và Monitoring: Node.js được sử dụng để xây dựng các dashboard hiển thị dữ liệu thời gian thực và các công cụ giám sát, giúp doanh nghiệp dễ dàng theo dõi hiệu suất và tình trạng của các hệ thống.
Node.js, với các ưu điểm như xử lý nhanh, mô hình bất đồng bộ và không chặn, đã trở thành công nghệ lựa chọn cho nhiều nhà phát triển và doanh nghiệp khi xây dựng các ứng dụng hiện đại và hiệu quả.
Cách cài đặt và sử dụng NodeJS
Hãy cùng xem cách bạn có thể tạo ứng dụng Node.js đầu tiên của mình. Phần này sẽ chỉ cho bạn cách chạy các tập lệnh Node.js từ dòng lệnh.
Cách tải xuống và cài đặt Node.js
Trước tiên, bạn cần tải xuống và cài đặt Node.js. Có nhiều cách khác nhau để bạn có thể thực hiện việc đó. Nếu bạn là người mới bắt đầu, tôi khuyên bạn nên tải xuống Node.js từ trang web chính thức (download node.js). Chọn phiên bản phù hợp với hệ điều hành của mình và tải xuống.
Cách kiểm tra phiên bản Node.js
Để kiểm tra phiên bản Node.js, hãy chạy lệnh node --version
trong terminal của bạn.
Nếu cài đặt thành công, bạn sẽ thấy phiên bản Node.js bạn đã cài đặt. Bạn sẽ nhận được phản hồi như ảnh chụp màn hình bên dưới.
Cách chạy Node.js từ dòng lệnh
Hãy cùng xây dựng một Hello World
ứng dụng đơn giản.
Tạo một thư mục dự án mới. Bạn có thể gọi nó là my-project.
Mở dự án trong trình soạn thảo mã của bạn. Bên trong thư mục, tạo một app.js
tệp.
Thêm mã sau vàoapp.js
Như bạn có thể thấy, đây là mã JavaScript.
Bạn có thể chạy tập lệnh trong dòng lệnh bằng cách chạy lệnh node <fileName>
. Trong trường hợp này, tên tệp là app.js
.
Chạy lệnh sau trong terminal để thực thi Hello world.
chương trình:
node app.js
Bạn sẽ thấy chuỗi “Hello world.” được ghi vào thiết bị đầu cuối của bạn như thế này.
Xin chúc mừng! Bạn vừa chạy ứng dụng Node.js đầu tiên của mình.
Chúng tôi biết rằng một bài đăng như thế này là không đủ để tìm hiểu tất cả những gì cần biết về Node.js. Nhưng hi vọng bài viết của TopDev đã cung cấp cho bạn cái nhìn tổng quan về Node.js là gì, đặc điểm và cách sử dụng Node.js
Nguồn tham khảo:
- www.freecodecamp.org/news/what-is-node-js/
- www.simplilearn.com/tutorials/nodejs-tutorial/what-is-nodejs
Xem thêm: