nodejs中exports與module.exports的實踐


只要是在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

^-^

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM