只要是在nodejs中寫自己的文件模塊就少不了會遇到module.exports和exports的使用,看別人的代碼大多都會使用“module.exports=exports=<對象/函數等>”怪異的串聯用法,一問原因,貌似都是雲里霧里,如此寫法更像是保守的防止性寫法。
這種問題除了看源代碼外,只能寫點代碼進行求證。
寫了兩個模塊文件,provider.js產生任意類型的對象, customer.js返回並輸出provider對象。
第一種情況:
provider.js,直接在exports上設置任意類型的對象。
exports = {name:'kxh'} /*exports = function(){ console.log('kxh'); }; exports = 'kxh';*/ console.log('*******provider-module***********'); console.log(module); console.log('*******provider-exports***********'); console.log(exports);
customer.js
var p = require('./provider'); console.log('*******customer-result***********'); console.log(p);
執行customer.js結果:
*******provider-module*********** { id: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js', exports: {}, parent: { id: '.', exports: {}, parent: null, filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\customer.js', loaded: false, children: [ [Circular] ], paths: [ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules', 'D:\\ProgramDemos\\Web\\nodejs\\node_modules', 'D:\\ProgramDemos\\Web\\node_modules', 'D:\\ProgramDemos\\node_modules', 'D:\\node_modules' ] }, filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js', loaded: false, children: [], paths: [ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules', 'D:\\ProgramDemos\\Web\\nodejs\\node_modules', 'D:\\ProgramDemos\\Web\\node_modules', 'D:\\ProgramDemos\\node_modules', 'D:\\node_modules' ] } *******provider-exports*********** { name: 'kxh' } *******customer-result*********** {}
從結果看,直接向exports上設置任意類型的對象都不會被require返回給調用模塊。require返回的是module.exports的空對象。
第二種情況:
provider.js,為exports設置任意類型的屬性。
exports.name = {firstName:'xh', lastName:'k'}; //exports.name = "kxh"; /*exports.printName = function(){ console.log("kxh"); };*/ console.log('*******provider-module***********'); console.log(module); console.log('*******provider-exports***********'); console.log(exports);
customer.js不變。
執行customer.js結果:
*******provider-module*********** { id: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js', exports: { name: { firstName: 'xh', lastName: 'k' } }, parent: { id: '.', exports: {}, parent: null, filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\customer.js', loaded: false, children: [ [Circular] ], paths: [ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules', 'D:\\ProgramDemos\\Web\\nodejs\\node_modules', 'D:\\ProgramDemos\\Web\\node_modules', 'D:\\ProgramDemos\\node_modules', 'D:\\node_modules' ] }, filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js', loaded: false, children: [], paths: [ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules', 'D:\\ProgramDemos\\Web\\nodejs\\node_modules', 'D:\\ProgramDemos\\Web\\node_modules', 'D:\\ProgramDemos\\node_modules', 'D:\\node_modules' ] } *******provider-exports*********** { name: { firstName: 'xh', lastName: 'k' } } *******customer-result*********** { name: { firstName: 'xh', lastName: 'k' } }
從結果看,為exports設置任意類型的屬性,module.exports保持同步,能被require返回出去。
第三種情況:
provider.js,為exports設置任意類型的屬性,並且為module.exports設置同名的或不同名的任意類型的屬性。
exports.name = {firstName:'xh', lastName:'k'}; //exports.name = "kxh"; /*exports.printName = function(){ console.log("kxh"); };*/ //module.exports.name = {firstName:'wf', lastName:'z'}; module.exports.mail = "kxh@kxh.com"; console.log('*******provider-module***********'); console.log(module); console.log('*******provider-exports***********'); console.log(exports);
customer.js不變。
執行customer.js結果:
*******provider-module*********** { id: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js', exports: { name: { firstName: 'xh', lastName: 'k' }, mail: 'kxh@kxh.com' }, parent: { id: '.', exports: {}, parent: null, filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\customer.js', loaded: false, children: [ [Circular] ], paths: [ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules', 'D:\\ProgramDemos\\Web\\nodejs\\node_modules', 'D:\\ProgramDemos\\Web\\node_modules', 'D:\\ProgramDemos\\node_modules', 'D:\\node_modules' ] }, filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js', loaded: false, children: [], paths: [ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules', 'D:\\ProgramDemos\\Web\\nodejs\\node_modules', 'D:\\ProgramDemos\\Web\\node_modules', 'D:\\ProgramDemos\\node_modules', 'D:\\node_modules' ] } *******provider-exports*********** { name: { firstName: 'xh', lastName: 'k' }, mail: 'kxh@kxh.com' } *******customer-result*********** { name: { firstName: 'xh', lastName: 'k' }, mail: 'kxh@kxh.com' }
從結果看,如果設置不同名的屬性,則為合並到module.exports並返回,如果是同名屬性則require返回的全是module.exports。
第四種情況:
provider.js,不論為exports設置社么樣類型的屬性,直接為module.exports設置了任意類型對象。
exports.name = {firstName:'xh', lastName:'k'}; //exports.name = "kxh"; /*exports.printName = function(){ console.log("kxh"); };*/ //module.exports = {name:'kxh'}; module.exports = function(){ console.log('kxh'); }; console.log('*******provider-module***********'); console.log(module); console.log('*******provider-exports***********'); console.log(exports);
customer.js不變。
執行customer.js結果:
*******provider-module*********** { id: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js', exports: [Function], parent: { id: '.', exports: {}, parent: null, filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\customer.js', loaded: false, children: [ [Circular] ], paths: [ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules', 'D:\\ProgramDemos\\Web\\nodejs\\node_modules', 'D:\\ProgramDemos\\Web\\node_modules', 'D:\\ProgramDemos\\node_modules', 'D:\\node_modules' ] }, filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js', loaded: false, children: [], paths: [ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules', 'D:\\ProgramDemos\\Web\\nodejs\\node_modules', 'D:\\ProgramDemos\\Web\\node_modules', 'D:\\ProgramDemos\\node_modules', 'D:\\node_modules' ] } *******provider-exports*********** { name: { firstName: 'xh', lastName: 'k' } } *******customer-result*********** [Function]
從結果看,不論為exports設置社么樣類型的屬性,直接為module.exports設置了任意類型對象,則require一律返回module.exports。
從上面的四種實踐結果來看:
require返回的是module.exports,在module.exports上可以設置函數、對象實例、基本類型的變量等,因此,一般就是module.exports作為模塊的到處就行了。
如果想用exports作為模塊的返回,那么就為它設置一個屬性,並且不要在module.exports上設置同名的屬性。
end
^-^