Nodejs模仿commonJS模块系统,内置的require函数很容易include存在于各个分离的文件中的模块。Require函数的基本功能是读取一个javaScript文件并且执行它,返回exports对象。一个模块的例子:
console.log("evaluating example.js"); var invisible = function () { console.log("invisible"); } exports.message = "hi"; exports.say = function () { console.log(message); }
因此,如果你运行var example =require(‘./example.js‘),结果是example作为一个对象,它的值等于如下:
{ message: "hi", say: [Function] }如果你想将exports 对象设置为一个函数或者一个新对象,你必须使用moudle.exports对象,举例:
module.exports = function () { console.log("hello world") } require(‘./example2.js‘)() //require itself and run the exports object
值得注意的是每次你重复require已经require的文件时,exports对象会缓存并且重复使用。请看如下解释:
node> require(‘./example.js‘) evaluating example.js { message: ‘hi‘, say: [Function] } node> require(‘./example.js‘) { message: ‘hi‘, say: [Function] } node> require(‘./example.js‘).message = "hey" //set the message to "hey" ‘hey‘ node> require(‘./example.js‘) //One might think that this "reloads" the file... { message: ‘hey‘, say: [Function] } //...but the message is still "hey" because of the module cache.
从上面的例子可以看出,example.js在第一次被 执行,随后的require()调用仅仅触发了模块的缓存,而不是重新又读取该文件。如上所示,这有时会产生副作用。
Require寻找文件的规则有点复杂。大概的规则是:
(1)如果文件不是以”/”或”./”开始时,它会认为是一个核心模块(并且本地的node模块会被检测)或者是一个在本地node_moudles目录中的依赖;
(2)如果文件是以”./”开始时,它会认为被requre的文件是一个相对路径的文件;
(3)如果文件是以”/”开始时,它会认为是绝对路径。注意:你可以省略”.js”,require会根据需要自动加上”.js”。更详细的信息请查看官方文档。
还有一点需要注意的是:如果传给require的是一个目录,它会在目录中首先寻找package.json,加载main属性的文件引用。否则,它会寻找index.js文件。