nodejs require exports module

环境

  • node = v7.9.0
  • os = macOS Mojave v10.14

准备

目录

-test

  • test-require.js
  • a.js
  • b.js
  • app.js

一、require

test-require.js

module.exports = function(){
   console.log('test require has run')
}

a.js

module.exports = function () {
    require('./test-require')
    console.log('a run')
}

b.js

module.exports = function () {
    require('./test-require')
    console.log('b run')
}

1.require用法

向app.js中加入以下代码,分别打开注释运行node app.js


var a = require('./a')
// var a = require('./a.js')
// var a = require('/Users/jyjin/workspace/gitProject/interview/a')
// var a = require('/Users/jyjin/workspace/gitProject/interview/a.js')
// var a = require('a')      // 错误
// var a = require('a.js')   // 错误

var b = require('./b.js')
a()
b()
console.log('app start...')
console.log('app start...')
结论

a.合法引用

require(’./a’) // 相对路径
require(’./a.js’)
require(’/Users/jyjin/workspace/gitProject/interview/a’) // 绝对路径
require(’/Users/jyjin/workspace/gitProject/interview/a.js’)

node app.js
a run
b run
app start...

b.错误引用

require(‘a.js’)
require(‘a’)

Error: Cannot find module 'a.js'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/jyjin/workspace/gitProject/interview/app.js:1:63)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
Error: Cannot find module 'a'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/jyjin/workspace/gitProject/interview/app.js:1:63)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)

2.require加载模式

修改test-require.js, 如下

console.log(‘require initilized …’) // <- 添加此句代码
module.exports = function () {
console.log(‘test require has run’)
}

运行node app.js, 结果如下

node app.js
require initilized ...
a run
b run
app start...
结论

多次重复require某个模块时,require只会加载一次

二、exports与module.exports

1.exports用法

通常我们最熟悉的用法,exports可以导出多个模块,module.exports只可以导出单个模块(require例子中所有的模块可以看出)

现新建test-exports.js

var count = 0
var increment = 5
var setIncrement = function (_increment) {
if (!_increment)
console.error(‘parameter _increment is required!’)
increment = _increment
}
var printCount = function () {
count += increment
console.log('count in exports: ', count)
}
exports.setIncrement = setIncrement
exports.printCount = printCount

修改app.js如下

var {setIncrement, printCount} = require(’./test-exports’)
setIncrement(10)
printCount();
printCount();
printCount();
setIncrement(2)
printCount()
printCount()
printCount()
console.log(‘app start…’)
运行结果

node app.js
count in exports:  10
count in exports:  20
count in exports:  30
count in exports:  32
count in exports:  34
count in exports:  36

通过运行结果可以看出:exports可以作为模块接口导出多个模块

向test-exports中加入以下代码

var isEq = (exports == module.exports)
console.log('isEq : ', isEq)
console.log('exports: ', exports)
console.log('module.exports: ', module.exports)
运行观察exports和module.exports

运行node app.js观察结果

node app.js
isEq   :  true
exports:  { setIncrement: [Function: setIncrement],
  printCount: [Function: printCount] }
module.exports:  { setIncrement: [Function: setIncrement],
  printCount: [Function: printCount] }
count in exports:  10
count in exports:  20
count in exports:  30
count in exports:  32
count in exports:  34
count in exports:  36
app start...

可见
exports导出是一个对象,因此test-exports的导出语句可以优化为

exports.setIncrement = setIncrement
exports.printCount = printCount
// 等价于下面代码:
exports = {setIncrement, printCount}

并且在没有设置module.exports的情况下,module.exports和exports相同。实际上,exports最终只是module.exports一个地址引用

结论
  • exports可以作为模块接口导出多个模块
  • exports作为模块导出的接口,导出的是一个对象
  • exports是module.exports的一个引用(此例子还不能证明引用,在下文举例证明),即在没有设置module.exports只设置了exports的情况下module.exports=exports**

2.exports是module.exports的一个引用

修改test-exports如下

var count = 0
var increment = 5
var printCount = function () {
count += increment
console.log('count in exports: ', count)
}
exports.printCount = printCount
module.exports = function () {
increment = 2
count += increment
this.printCount = function () {
console.log('count in module.exports: ', count)
}
}
var isEq = (exports == module.exports)
console.log('isEq : ', isEq)
console.log('exports: ', exports)
console.log('module.exports: ', module.exports)

分别为exports和module.exports挂一个printCount方法,且实现不同,看谁覆盖谁

1.假设exports有效

修改app.js如下

var te = require(’./test-exports’)
te.printCount()

运行node app.js结果

node app.js
isEq   :  false
exports:  { printCount: [Function: printCount] }
module.exports:  function () {
    increment = 2
    count += increment
    this.printCount = function () {
        console.log('count in module.exports: ', count)
    }
}
/Users/jyjin/workspace/gitProject/interview/app.js:26
te.printCount()
   ^

TypeError: te.printCount is not a function
    at Object.<anonymous> (/Users/jyjin/workspace/gitProject/interview/app.js:26:4)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:423:7)
    at startup (bootstrap_node.js:147:9)
    at bootstrap_node.js:538:3

显然
此时exports和module.exports不相同,并且没有办法通过te.printCount()调用printCount方法,也就是说exports没有生效。

假设exports生效不成立

那module.exports有没有生效?

2.假设module.exports有效

再修改app.js如下

var t = new te()
t.printCount();

注意:

  • 成员方法调用需要new进行实例化

运行node app.js结果

node app.js
isEq   :  false
exports:  { printCount: [Function: printCount] }
module.exports:  function () {
    increment = 2
    count += increment
    this.printCount = function () {
        console.log('count in module.exports: ', count)
    }
}
count in module.exports:  2
app start...

运行成功!

结论

当exports与module.exports不相同时,模块的导出以module.exports为准
结合exports使用的例子,可以看出exports仅仅是module.exports的一个地址引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值