Tìm hiểu về require trong Node.js

Tìm hiểu về require trong Node.js

Tin ngắn hàng ngày dành cho bạn
  • Từ lâu rồi suy nghĩ làm thế nào để tăng sự hiện diện thương hiệu, cũng như người dùng cho blog. Nghĩ đi nghĩ lại thì chỉ có cách chia sẻ lên mạng xã hội hoặc trông chờ họ tìm kiếm, cho đến khi...

    In cái áo này được cái tắc đường khỏi phải lăn tăn, càng đông càng vui vì hàng trăm con mắt nhìn thấy cơ mà 🤓

    (Có tác dụng thật nha 🤭)

    » Xem thêm
  • Một vòng của sự phát triển nhiều dự án khá là thú vị. Tóm tắt lại trong 3 bước: Thấy một cái gì đó phức tạp -> Làm cho nó đơn giản đi -> Thêm thắt tính năng cho đến khi nó phức tạp... -> Quay trở lại vòng lặp mới.

    Tại sao lại như vậy? Để mình lấy 2 ví dụ cho các bạn thấy.

    Markdown ra đời với mục tiêu tạo ra một định dạng văn bản thô "dễ viết, dễ đọc, dễ dàng chuyển thành một dạng gì đó như HTML". Vì thời đó chẳng ai đủ kiên nhẫn mà vừa ngồi viết vừa thêm định dạng cho văn bản hiển thị ở trên web như thế nào. Ấy vậy mà giờ đây người ta đang "nhồi nhét" hoặc tạo ra các biến thể dựa trên markdown để bổ sung thêm nhiều định dạng mới đến mức... chẳng nhớ nổi hết cú pháp.

    React cũng là một ví dụ. Từ thời PHP, việc khát khao tạo ra một cái gì đó tách biệt hẳn giao diện người dùng và phần xử lý logic chính của ứng dụng thành 2 phần riêng biệt cho dễ đọc, dễ viết. Kết quả là các thư viện UI/UX phát triển rất mạnh mẽ, mang lại khả năng tương tác với người dùng rất tốt, còn phần logic ứng dụng thì nằm ở một máy chủ riêng biệt. Bộ đôi Front-end, Back-end cũng từ đấy mà thịnh hành, không thể thiếu anh bồi bàn REST API. Ấy vậy mà giờ đây React trông cũng không khác biệt gì so với PHP là mấy, kéo theo là cả Vue, Svelte... lại cùng quy tất cả về một mối.

    Cơ mà không phải vòng lặp là xấu, ngược lại vòng lặp này mang tính tiến hoá nhiều hơn là "cải lùi". Nhiều khi lại tạo ra được cái hay hơi cái cũ thế là người ta lại dựa trên cái hay đó để tiếp tục lặp. Nói cách khác là chắc lọc tinh hoa từng tí một tí một á 😁

    » Xem thêm
  • Song song với các dự án chính thức thì thi thoảng mình vẫn thấy các dự án "bên lề" nhằm tối ưu hoặc cải tiến ngôn ngữ theo khía cạnh nào đó. Ví dụ nature-lang/nature là một dự án hướng tới cải tiến Go, mang lại một số thay đổi nhằm giúp cho việc sử dụng Go trở nên thân thiện hơn.

    Nhìn lại mới thấy hao hao JavaScript 😆

    » Xem thêm

Vấn đề

Node.js sử dụng CommonJS để triển khai hệ thống module và require là lệnh để yêu cầu sử dụng một module trong một file xác định. Chức năng cơ bản của require đó là nó sẽ đọc một file, thực thi và sau đó trả lại các đối tượng được exports.
Ví dụ một module như sau:

console.log("example.js");

const invisible = function () {
  console.log("invisible");
}

exports.message = "hi";

exports.say = function () {
  console.log(exports.message);
}

Khi đó:

var example = require('./example.js')
console.log(example);

Chúng ta sẽ thấy kết quả như là:

example.js
{
  message: "hi",  
  say: [Function]
}

Hoặc chúng ta cũng có thể sử dụng module.exports để exports ra một hàm hoặc một đối tượng mới.

Ví dụ:

module.exports = function () {
  console.log("hello world");
}

Khi đó

require('./example2.js')(); // return "hello world"

Một điều cần lưu ý là mỗi lần require một tệp đã được require trước đó, các đối tượng được exports sẽ được lưu vào bộ nhớ đệm (cache) và sử dụng lại.

Ví dụ:

node> require('./example.js')
example.js
{ message: 'hi', say: [Function] }
node> require('./example.js')
{ message: 'hi', say: [Function] }
node> require('./example.js').message = "hey" // gán message thành "hey"
'hey'
node> require('./example.js') // lúc này chúng ta sẽ nghĩ require giống như là yêu cầu require mới lại file...  
example.js
{ message: 'hey', say: [Function] } // nhưng kết quả message đã bị gán thành "hey"

Như các bạn có thể thấy ở trên, example.js được require một lần duy nhất, sau đó tất cả các lệnh gọi require tiếp theo sẽ chỉ lấy ra trong bộ nhớ đệm, thay vì đọc lại tệp. Điều này đôi khi có thể tạo ra một số trường hợp không mong muốn như ở ví dụ trên khi chúng ta vô tình thay đổi các thuộc tính.

Các quy tắc về require có thể hơi phức tạp, nhưng có một số quy tắc chung đơn giản như là nếu tệp không bắt đầu bằng "./" hoặc "/", thì nó được coi là built-in module (core), hoặc là một phần phụ thuộc trong thư mục node_modules. Nếu tệp bắt đầu bằng "./" thì nó được coi là tệp với đường dẫn tương đối. Nếu tệp bắt đầu bằng "/", nó được coi là tệp với đường dẫn tuyệt đối.

Lưu ý: có thể bỏ qua đuôi ".js", require sẽ tự động thêm vào nếu cần.

Ngoài ra, nếu chúng ta require chỉ đến cấp thư mục nó sẽ tự động tìm file index.js, nếu không có sẽ gây ra một lỗi module không tồn tại.

Cao cấp
Hello

Tôi & khao khát "chơi chữ"

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên ngay!

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (2)

Nội dung bình luận...
Avatar
Ẩn danh1 năm trước

Cho tôi hỏi là có thể exports một hằng số được không

Trả lời
Avatar
Xuân Hoài Tống1 năm trước

Được bạn. Trong JavaScript/Node.js hầu như dữ liệu gì cũng có thể exports được bạn ạ.

Avatar
Trịnh Cường3 năm trước

Bài viết rất bổ ích.cảm ơn tác giả nhiều

Trả lời