在Node.js模块系统中,每个文件都被视为独立的模块
module.exports属性可以被赋予一个新的值(例如函数或对象)
访问主模块
Node中存在两个变量:require.main
和module
,假如我们执行
// 如果执行 node foo.js
console.log(require.main === module) //true
// 如果通过require('./foo.js')
console.log(require.main === module) //false
因为module
提供了一个filename
属性(通常等同于__filename),所以可以通过检查require.main.filename
来获取当前应用程序的入口点
缓存
模块在第一次加载后会被缓存,这也意味着(类似其他缓存机制)如果每次调用require('foo')
都解析到同一个文件,则返回相同的对象。多次调用require('foo')
不会导致模块的代码被执行多次,借助它,可以返回‘部分完成’的对象,从而允许加载依赖的依赖,即使他们会导致循环依赖
如果想要多次执行一个模块,可以导出一个函数,然后调用
核心模块
Node有些模块会被编译成二进制,核心模块定义在Node.js源码的lib/
目录下。
require
总是会优先加载核心模块,例如require('http')
始终返回内置的HTTP模块,即使有同名文件
模块包装器
在执行模块代码之前,Node.js会使用一个如下的函数包装器将其包装:
(function(exports,require,module,__filename,__dirname){
// 模块的代码实际上在这里
})
__dirname
当前模块的文件夹名称。等同于__filename
的path.dirname()
的值
__filename
当前模块的文件名称--解析后的绝对路径
exports
这是一个对于module.exports
的更简短的应用形式
module
对当前模块的应用
比如
console.log(module)
require.cache
被引入的模块将被缓存在这个对象中,从此对象中删除键值对将会导致下一次require
重新加载被删除的模块
不能删除native addons
(原生插件),因为他们的重载会导致错误
require.main
Module {
id: '.',
exports: {},
parent: null,
filename: '/absolute/path/to/entry.js',
loaded: false,
children: [],
paths:
[ '/absolute/path/to/node_modules',
'/absolute/path/node_modules',
'/absolute/node_modules',
'/node_modules' ] }
require.resolve(request[, options])
-
request
<string> 需要解析的模块路径。 -
options
<Object> *paths
<Array> 解析模块的起点路径。此参数存在时,将使用这些路径而非默认解析路径。 注意此数组中的每一个路径都被用作模块解析算法的起点,意味着node_modules
层级将从这里开始查询。 - Returns: <string>
使用内部的 require()
机制查询模块的位置, 此操作只返回解析后的文件名,不会加载该模块。
require.resolve.paths(request)
返回一个数组,其中包含解析 request
过程中被查询的路径。 如果 request
字符串指向核心模块(例如 http
或 fs
),则返回 null
。
module 对象
module.exports
module.exports
对象是由模块系统创建的。 有时这是难以接受的;许多人希望他们的模块成为某个类的实例。 为了实现这个,需要将期望导出的对象赋值给 module.exports。 注意,将期望的对象赋值给 exports 会简单地重新绑定本地 exports 变量,这可能不是期望的。
**对module.exports
的赋值必须立即完成
exports 快捷方式
它有一个快捷方式,以便 module.exports.f = ...
可以被更简洁地写成 exports.f = ...
。
当 module.exports 属性被一个新的对象完全替代时,也会重新赋值 exports,例如:
module.exports = exports = function Constructor() {
// ... 及其他
};
`
网友评论