初学Node(三)模块系统

模块系统node

  Node根据CommonJS规范实现了一套本身的模块机制,可使用require()导入一个模块,使用module.exports导出一个模块。json

require使用缓存

  在Node中咱们可使用require()导入一个模块,此时咱们就会得到一个被导入模块的对象,咱们就能够利用这个对象来完成一些操做,例如:函数

var fs = require("fs");
fs.readFile("content.txt",function(err,data){
    if(err){
        return console.log("读取文件错误!");
    }
    console.log(data.toString());
})

  咱们经过require()将fs模块导入,此时咱们就经过得到的fs模块的对象来实现对文件的操做。ui

  在Node中模块分为核心模块和文件模块,核心模块即被被编译成二进制代码的模块,是Node自带的一些模块。文件模块即咱们本身编写的模块,不管哪一种模块均可以经过require()函数来引入。spa

  require()的参数有四种不一样的形式,分别为:命令行

  核心模块:require("fs")code

  相对文件路径:require("../xxx")对象

  绝对文件路径:require("/xxx")blog

  非核心模块的文件模块:require("xxx")

  加载模块的过程以下图所示:

require按照路径加载模块

  例如咱们经过require("X")加载一个模块,首先会去文件模块缓存区中查找有没有该模块的缓存,若是缓存区中存在该模块,则直接返回。若是不存在该模块就会判断X的类型,若是是加载一个原生模块,就会按原生模块缓存区,原生模块这样的顺序去查找该模块,若是在原生模块缓存区中找到就会直接返回模块对象,若是在原生模块中找到就会在原生模块缓存区中加入该模块以方便下一次的使用,而后返回模块。

  若是X是一个路径类型首先把X当作文件按照X、X.js、X.json、X.node来查找该模块,找到以后加入到文件模块缓存区中而后返回该模块。若是没有找到,则把X当作是一个目录,在X里面按照index.js、index.json、index.node的顺序依次查找,若是目录中存在package.json则优先加载main属性对应的文件,在找到以后将模块加入到文件模块缓存区中而后返回该模块。

  咱们在桌面上新建两个文件夹,分别为first和second,在first中新建first.js文件,first.js内容以下:

var name = "zt"
module.exports.show = function(){
    console.log(name);
}

  在sencond中新建main.js文件,main.js文件内容以下:

var first = require("../first");
first.show();

  在命令行中进入sencond文件node main.js执行,会报Error,不能找到first。咱们按照上面的过程来排除错误,第一次加载文件缓存区中没有,也不是原生模块,此时就会按照路径的方式来加载first模块,首先把它当成一个文件,即在桌面中按照first、first.js、first.json、first.node的顺序来查找,都不存在,而后把first看错一个目录,而后在first文件内去查找,首先查看有没有package.json文件,存在就会加载main属性对应的文件,不存在就按照index.js、index.json、index.node的顺序来查找,仍然找不到最终就会报错。

  按照上面的流程咱们能够经过三种方式来修改:

  1:在桌面上新建一个first.js,这时当按照文件来查找时就能够找到first.js,而后载入模块。

  2:在first文件夹中将first.js更名为index.js,这样在按照文件不能查找到,按照目录查找时就能够找到index.js,而后载入模块。

  3:在first文件夹中初始化一个package.json文件,main属性值为first.js,这样在按照目录查找时在目录中存在package.json文件就会加载main属性对应的文件。

require按照模块去查找

  例如在second的main.js中经过require("first")这种方式来加载first模块,使用这种方式来加载模块优先在当前文件夹(second文件夹)中查找node_modules文件夹,在node_modules文件夹中去查找first模块(在node_modules文件夹中也是按照路径的那个套路来查找),而后在sencond的父级下的node_modules文件下去查找first模块,按照这种方式一直查找下去,咱们能够经过module.paths来查看查找的路径:

console.log(module.paths);

  在sencond文件夹中新建node_modules文件夹,而后把first文件夹放入到node_modules文件夹中,这样main.js中的require("first")就能够找到first模块了。

module.exports导出模块

  能够在一个文件中使用module.exports导出一个模块,这样在require()时就可使用导出的属性或者方法。以上面的first.js为例咱们在first.js中使用module.exports导出了show方法,这样咱们在使用require()以后获取到的对象就可使用show方法了。

  Node对module.exports的使用作了一些简化处理让咱们在导出时可使用exports:

module.exports = exports = {};

  module.exports和exports共用一个引用,这样就能够经过exports来收集属性:

var name = "zt"
exports.show = function(){
    console.log(name);
}

  经过module.exports = exports = {},这样在使用require()函数时得到的module.exports对象也就有了exports收集的属性。

  若是module.exports从新赋值module.exports和exports的引用关系也就断开了,而require()函数返回的是module.exports对象,也就不能获得exports收集的属性了,因此在使用时不要混用。

相关文章
相关标签/搜索