环境
- 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的一个地址引用