什么是模块?在node中,文件和模块是一一对应的,即一个文件就是一个模块,每个模块都有自己的作用域。我们用var来声明一个变量,它不是全局的,属于当前模块下模块的加载和使用。在node中,我们使用require('module')的形式将一个模块引入到我们当前的文件中。require路径也有几种写法:模块路径可以以/开头,表示绝对路径。模块路径以./开头,表示从当前目录开始的相对路径。如果模块路径不是以/或./开头,那么这个Modules要么是核心模块,要么通过npm安装在node_modules文件夹中。看到上面不同的路径写法,我们想起了在web中导入当前文件夹下的文件时不需要加./,但是在node中使用或不使用./或/开头的路径时,有有很大的不同。模块加载机制首先根据加载模块的文件名进行查找。如果没有找到,它会在模块文件名中加上.js的后缀。如果没有找到,会在文件名后缀上加上.json,如果还没有,会在文件名上加上.node的后缀,再搜索就找不到了,并且会抛出异常。模块数据的使用与浏览器中的不同。在node中,每个模块都有自己的模块中用var声明的变量作用域是在模块内部,而不是全局节点。但是您忘记使用var进行变量声明。恭喜,忘记在浏览器中使用它的效果是一样的。该变量也会挂在全局对象上。只是在node中,global对象是全局的,而不是浏览器中的window。我们看一个简单的例子:我们可以简单的从a.js和b.js这两个文件中看到node声明变量的作用域。a.js:vara='这是a声明的变量';console.log('这是a.js模块');b.js:require('./2.js');console.log('bbbb');console.log(a);console.log(global.a);节点b.js输出:这是2.js模块bbbbconsole.log(a);//ReferenceError:aisnotdefinedastoremovevar之后会发生什么,自己试一下^^暴露模块APImodule,module.exports,exports如上代码所示,在nodejs中不能直接获取另一个模块中的变量函数等。为了让模块暴露一个API作为require调用的返回值,我们需要通过module.exports或exports提供对模块内部变量的访问。默认情况下,每个模块都暴露一个空对象,如果你想在该对象上添加属性,只需使用导出。看这个例子:module_a.js:console.log(exports===module.exports)exports.name='module_a.js'exports.data='thisismodule_a.jsdata'exports.getDate=function(){返回新日期();}module_b.js:vara=require('./module_a.js')console.log(a.name)console.log(a.data)console.log(a.getDate())nodemodule_b.jsoutput:truemodule_a.jsthisismodule_a.jsdataThuSep22201622:23:59GMT+0800(CST)可以看到模块内部的exports其实是对module.exports的引用,使用引入require模块之后,a是一个对象。可以看出,外部模块通过require(module)方法加载模块,函数返回加载模块的module.exports对象。如果给module.exports对象一个一个添加属性不满足你的需求,你也可以添加module。导出被完全重写。我们重写上面两个文件:一个OK');nodemodule_b.jsoutput:printf:ok有一点需要注意:直接覆盖exports或者module.exports让模块导出一个值,这样会破坏exports和module.exports的引用关系。这是node的模块系统的学习,我的理解有限。如有错误请指出,谢谢!本文地址:https://guowenfh.github.io/2016/10/15/node-module-system/
