Câu trả lời là: lý do lịch sử.
Bạn nói đúng, chúng tôi chỉ có thể có module
và exports
sẽ không cần thiết nhưng vẫn còn ở đó để tương thích ngược.
Nó từng là thời điểm khi trình bao bọc mô-đun được thay đổi trong mọi bản phát hành bản vá.
Trong Node 0.1.11 module wrapper là:
var wrapper = "function (__filename) { "+
" var onLoad; "+
" var onExit; "+
" var exports = this; "+
content+
"\n"+
" this.__onLoad = onLoad;\n"+
" this.__onExit = onExit;\n"+
"};\n";
Xem: https://github.com/nodejs/node/blob/v0.1.11/src/node.js#L167#L177
Như bạn có thể thấy exports
là giống như this
rằng chức năng bao bọc được gọi với. Bạn không thể trao đổi nó với một đối tượng mới và thậm chí bạn không thể thêm một số khóa dành riêng cho nó - ví dụ: bạn không thể xuất một cách an toàn một tài sản có tên là __onExit
.
Sau đó, trong 0.1.12 đó là:
var wrapper = "function (__filename, exports) { " + content + "\n};";
Xem: https://github.com/nodejs/node/blob/v0.1.12/src/node.js#L243-L245
Ở đây exports
là một đối tượng cung cấp là một trong những tranh cãi nhưng bạn không thể trao đổi nó với một đối tượng mới, bạn chỉ có thể thêm hoặc loại bỏ các thuộc tính khỏi đối tượng mà bạn nhận được.
Sau đó, 0.1.13 là người đầu tiên có điều này, tức là require
và include
:
var wrapper = "function (__filename, exports, require, include) { " + content + "\n};";
Xem: https://github.com/nodejs/node/blob/v0.1.13/src/node.js#L225-L227
Sau đó 0.1.14 là người đầu tiên có __module
(với dấu gạch dưới) trong các wrapper (và rằng giảm include
):
var wrapper = "var __wrap__ = function (__module, __filename, exports, require) { "
+ content
+ "\n}; __wrap__;";
Xem: https://github.com/nodejs/node/blob/v0.1.14/src/node.js#L280-L284
Và 0,1.16 là người đầu tiên có một cuộc tranh luận module
(không có dấu gạch dưới) trong wrapper:
var wrapper = "var __wrap__ = function (exports, require, module, __filename) { "
+ content
+ "\n}; __wrap__;";
Xem: https://github.com/nodejs/node/blob/v0.1.16/src/node.js#L444-L448
Nó được thay đổi nhiều lần sau đó nhưng đây là thời gian mà module
đã giới thiệu làm các exports
không cần thiết nữa nhưng vẫn còn là một phím tắt hữu ích, cho phép bạn sử dụng:
exports.a = 1;
exports.b = 2;
exports.c = 3;
thay vì:
0.123.
module.exports.a = 1;
module.exports.b = 2;
module.exports.c = 3;
mặc dù trong thực tế nếu không có exports
sau đó người ta sẽ thường viết:
const exports = module.exports;
exports.a = 1;
exports.b = 2;
exports.c = 3;
hoặc nhiều khả năng:
module.exports = {
a: 1,
b: 2,
c: 3,
};
hay, có một số kiểm tra trong các công cụ phân tích tĩnh:
const a = 1;
const b = 2;
const c = 3;
module.exports = { a, b, c };
Có nhiều cách để làm điều đó, đó là một cơ chế linh hoạt.
Đánh tôi với nó. Đã sớm hơn tôi nhớ. – OrangeDog