module.exports: 'Cửa Hàng' Code Của Bạn Trong Node.js!
Nodejs

module.exports: 'Cửa Hàng' Code Của Bạn Trong Node.js!

Author

Admin System

@root

Ngày xuất bản

22 Mar, 2026

Lượt xem

2 Lượt

"module.exports"

Chào các "coder nhí" Gen Z, hôm nay anh Creyt sẽ "bung lụa" một khái niệm nghe thì hàn lâm nhưng thực ra "dễ như ăn kẹo" trong Node.js, đó là module.exports. Nghe tên thôi đã thấy mùi "công xưởng" rồi đúng không? Đừng lo, anh sẽ biến nó thành câu chuyện "cửa hàng tạp hóa" cho các em dễ hình dung.

1. module.exports là gì mà "hot" thế? (Giải mã từ A-Z)

Này, các em cứ hình dung thế này: project của chúng ta không phải là một cái "nhà kho tổng" đổ tất cả mọi thứ vào một chỗ, hỗn độn như "cái chợ chiều" đâu. Mà nó phải là một "siêu thị" với các quầy hàng, gian hàng được sắp xếp gọn gàng, mỗi gian bán một loại mặt hàng riêng biệt.

Mỗi file JavaScript trong Node.js "mặc định" được coi là một "gian hàng" độc lập, một "module" riêng. Và module.exports chính là cái "menu" hoặc cái "bảng hiệu" mà gian hàng đó treo lên, để "khoe" với các gian hàng khác (hay các file khác) rằng: "Này, tao có món này ngon lắm, mày muốn dùng không?" Nó là cách bạn quyết định những gì sẽ được chia sẻ ra bên ngoài từ file hiện tại của bạn.

Tóm lại: module.exports là cơ chế của Node.js (theo chuẩn CommonJS) cho phép một module (file) "xuất" các giá trị (biến, hàm, đối tượng, class) để các module khác có thể "nhập" (import/require) và sử dụng lại. Nó giúp chúng ta:

  • Phân chia code: Giúp project sạch sẽ, dễ đọc, dễ bảo trì hơn, tránh "spaghetti code" (code rối như mì ống).
  • Tái sử dụng: Viết một lần, dùng nhiều nơi. "Đỡ phải copy-paste mỏi tay"!
  • Độc lập: Mỗi module làm tốt một nhiệm vụ riêng, giảm thiểu sự phụ thuộc lẫn nhau.

2. "Thực đơn" code: Code Ví Dụ minh hoạ

Giờ thì chúng ta cùng xem cách "treo bảng hiệu" và "gọi món" nhé.

Ví dụ 1: Xuất một "món" duy nhất (một hàm)

Giả sử bạn có một file math.js chuyên làm nhiệm vụ tính toán.

// math.js
function add(a, b) {
  return a + b;
}

// "Treo bảng hiệu" món "add" ra ngoài
module.exports = add;

Và giờ, trong file app.js, bạn muốn "gọi món" add này:

// app.js
// "Gọi món" từ gian hàng "./math.js"
const congHaiSo = require('./math'); 

console.log(congHaiSo(10, 5)); // Output: 15

Đơn giản đúng không? module.exports = add; có nghĩa là, khi ai đó require('./math'), họ sẽ nhận được chính cái hàm add đó.

Ví dụ 2: Xuất một "combo" nhiều món (một đối tượng)

Thông thường, một module sẽ có nhiều thứ muốn chia sẻ. Lúc này, chúng ta sẽ "đóng gói" chúng vào một đối tượng (object).

// calculator.js
const PI = 3.14159;

function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

// "Treo bảng hiệu" một combo các món
module.exports = {
  PI: PI,
  add: add,
  tru: subtract, // Đổi tên cho dễ gọi ở ngoài
  nhan: (a, b) => a * b // Xuất luôn hàm mũi tên
};

Và đây là cách bạn "gọi combo" trong main.js:

// main.js
const myCalculator = require('./calculator');

console.log(myCalculator.PI);      // Output: 3.14159
console.log(myCalculator.add(10, 5)); // Output: 15
console.log(myCalculator.tru(10, 5)); // Output: 5
console.log(myCalculator.nhan(4, 2)); // Output: 8

Ví dụ 3: "Exports" "tưởng bở" và module.exports "thật sự"

Đây là cái bẫy mà nhiều bạn mới học Node.js hay mắc phải. Trong Node.js, có một biến exports cũng được dùng để xuất. Thực ra, exports chỉ là một tham chiếu (một cái tên gọi khác) đến module.exports ban đầu (là một đối tượng rỗng {}).

Gợi Ý Đọc Tiếp
Querystring Node.js: Giải mã URL, data vibes cho Gen Z!

5 Lượt xem

  • Nếu bạn gán thuộc tính cho exports (ví dụ: exports.tenMon = giaTri;), bạn đang thêm thuộc tính vào đối tượng mà module.exports đang trỏ tới. Cách này hoạt động.
  • Nhưng nếu bạn gán thẳng cho exports (ví dụ: exports = { ... };), bạn đang làm cho exports trỏ tới một đối tượng hoàn toàn mới, và lúc này module.exports vẫn trỏ tới đối tượng rỗng ban đầu. Cách này sẽ không hoạt động như bạn mong đợi.

Luôn nhớ: module.exports là cái "chốt hạ" cuối cùng quyết định cái gì sẽ được xuất ra. Anh em cứ dùng module.exports là "ăn chắc mặc bền" nhất.

// trickyModule.js

// Cách này OK: Thêm thuộc tính vào đối tượng mà module.exports đang trỏ tới
exports.greeting = 'Hello from exports!';
exports.sayHi = () => 'Hi there!';

// CÁCH NÀY KHÔNG OK: exports bị gán lại, nhưng module.exports thì không!
// exports = { name: 'Creyt' }; // Dòng này sẽ làm mất hiệu lực của greeting và sayHi khi require

// CÁCH NÀY LUÔN OK: Gán trực tiếp cho module.exports
// module.exports = { name: 'Creyt', age: 30 }; // Nếu dùng dòng này, greeting và sayHi sẽ bị ghi đè

Khi require('./trickyModule'):

  • Nếu chỉ dùng exports.greetingexports.sayHi, bạn sẽ nhận được { greeting: 'Hello from exports!', sayHi: [Function] }.
  • Nếu bạn thêm dòng exports = { name: 'Creyt' }; và không có module.exports = ... nào khác, bạn sẽ nhận được { greeting: 'Hello from exports!', sayHi: [Function] }. Dòng exports = { name: 'Creyt' }; bị bỏ qua!
  • Nếu bạn thêm dòng module.exports = { name: 'Creyt', age: 30 };, bạn sẽ nhận được { name: 'Creyt', age: 30 }. Mọi thứ bạn gán cho exports trước đó đều bị ghi đè.

Lời khuyên từ Creyt: Để tránh nhầm lẫn, hãy luôn dùng module.exports = ... khi bạn muốn xuất một giá trị duy nhất hoặc một đối tượng tổng hợp các giá trị. Coi exports như một biến "tạm" thôi.

Illustration

3. Mẹo vặt "hack não" và Best Practices từ Creyt

  • "Đồng phục" code: Hãy thống nhất cách bạn xuất code. Hoặc luôn dùng module.exports = { ... } cho đối tượng, hoặc luôn dùng exports.tenMon = ... cho từng món lẻ. Đừng "nửa nạc nửa mỡ" mà loạn.
  • "Kín cổng cao tường": Chỉ xuất những gì "cần thiết" để các module khác sử dụng. Những hàm, biến "nội bộ" chỉ phục vụ cho module của bạn thì cứ để private, đừng "khoe" ra làm gì. Như vậy mới "bảo mật" và dễ quản lý.
  • Tên gọi "sang chảnh": Đặt tên cho các hàm, biến bạn xuất sao cho rõ ràng, dễ hiểu. "Đừng đặt tên kiểu 'func1', 'dataA' nhé, nghe 'phèn' lắm!" (Đừng dùng tiếng Anh kiểu 'function1', 'dataA' nhé, nghe 'phèn' lắm!)
  • Tương lai gọi tên ES Modules: Hiện tại Node.js vẫn dùng module.exports (CommonJS) là chính. Nhưng tương lai là của ES Modules (import/export). Cứ học vững cái này đã, cái kia từ từ "chiến" sau.

4. "Ứng dụng thực tế" - Ai đang dùng module.exports?

"Hỏi ngược lại thì đúng hơn: ai không dùng mới là lạ!" Bất kỳ dự án Node.js nào, từ nhỏ đến lớn, đều sử dụng module.exports (hoặc ES Modules) để cấu trúc code.

  • Express.js: Khi bạn định nghĩa các route, middleware, controller, service, model... trong một ứng dụng Express, bạn đều dùng module.exports để "xuất" chúng ra và "nhập" vào file app.js chính.
  • Các thư viện NPM: Hầu hết các thư viện bạn cài từ npm (như lodash, axios, moment...) đều được xây dựng dựa trên cơ chế module này để bạn có thể require và sử dụng chúng.
  • Microservices: Trong kiến trúc microservices, mỗi service là một "gian hàng" độc lập, "xuất" ra các API của nó để các service khác có thể "gọi" đến.

5. Thử nghiệm và Nên dùng cho case nào?

Anh Creyt đã "thử" qua đủ loại cách rồi, và đây là lời khuyên chân thành:

  • Dùng module.exports = một_giá_trị_duy_nhất; khi: Module của bạn chỉ có một nhiệm vụ chính yếu và bạn muốn xuất thẳng cái nhiệm vụ đó (ví dụ: một hàm tiện ích, một class duy nhất). Rất gọn gàng và rõ ràng.

    • Ví dụ: module.exports = new DatabaseConnection(); hoặc module.exports = authenticateUser;
  • Dùng module.exports = { key1: value1, key2: value2, ... }; khi: Bạn muốn xuất nhiều thứ từ một module. Đây là cách phổ biến nhất và được khuyến khích vì nó rõ ràng và linh hoạt. Nó giúp bạn tổ chức các "món hàng" của mình thành một "combo" có tên.

    • Ví dụ: module.exports = { connectDB, getUser, createUser };
  • Tránh dùng exports = { ... };: Như đã giải thích ở mục 2, nó sẽ không hoạt động như bạn nghĩ và dễ gây nhầm lẫn. Hãy luôn nhớ module.exports là "ông chủ" cuối cùng.

Vậy đó, module.exports không phải là cái gì quá "hack não" đúng không? Nó chỉ là cách chúng ta tổ chức code cho "ngon lành cành đào" hơn thôi. Hãy thực hành nhiều vào để "master" nó nhé các Gen Z tương lai của làng công nghệ!

Thuộc Series: Nodejs

Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!

#tech #cyberpunk #laravel
Chỉnh sửa bài viết

Bình luận (0)

Vui lòng Đăng Nhập để Bình luận

Hỗ trợ Markdown cơ bản
Nguyễn Văn A
1 ngày trước

Tính năng này đỉnh quá ad ơi, chờ mãi mới thấy một blog Tiếng Việt có UI/UX xịn như vầy!