NodeJS学习笔记(二) 模块与包_基础部分

在NodeJS中,虽然模块与包这部分内容看似很简单,但是初学node,还是要把这部分内容搞懂,不然到后面学习NodeJS网络编程过程中会出现各种不好理解的错误。在这部分内容中,准备分两个章节

  à模块与包基础部分

  à模块与包深入部分。

模块与包基础部分

在这一部分中,我是用的参考书《Node.js开发指南》中奖的很详细,现总结学习笔记如下:

--------模块--------

路径问题

我的理解就如同java中的类文件。通过目录的索引方式索引。使用nodejs中提供的require函数来调用其他模块。模块都是基于文件的,在node中模块可以是javascript代码文件,json文件或编译过的CC++扩展

路径管理也同java的类似:

  1. /.../.../xxx.js表示绝对路径
  2. ./xxx.js表示相对路径
  3. 不加/.../又不加./的话,则该模块要么是核心模块,要么是从 一个node_modules文件夹加载

在第三行中提到的核心模块即是nodejs本身提供的模块,也叫原生模块。这部分会在下面一个章节模块与包深入部分详细讲解。Mode_modules也叫做nodejs的中间件。比如我们要使用Express框架,npm –install –g express后,即可在文件中使用

  1. var express = require('express');

require()

在我的使用过程中,在使用require()时要注意一点。在require('./xxxx')这条语句,可以使引入的一个xxx.js文件,也可以是引入的一个xxx目录的包。容易造成奇异,代码阅读的时候很容易混乱。在这里推荐,模块的引入最好加上xxx.js拓展名。

模块的创建及加载

1:在node中,通常一个文件就是一个模块。

文件和模块是一一对应的。在java中我们可以通过构造引入类的对象,通过对象访问类中的成员变量和方法。在node中通过在模块中生命的exports方法名来提供对外接口。创建module.js:

  1. var name;
  2. exports.setName = function(nameArg){
  3.    name = nameArg;
  4. }
  5. exports.sayHello = function(){
  6.    console.log('Hello '+name + '!');
  7. }

在同一目录下创建getmodule.js

  1. var myModule = require('./module.js');
  2. myModule.setName('wenlonghor');
  3. myModule.sayHello();

输出结果:Hello wenlonghor!

2:require的单次加载

Require通常不会重复加载模块,这跟node的加载机制有关,每一个模块都会有缓存,包括原生模块和自己新创建的模块。在这里只需要了解一下,在后面深入讲解模块与包的部分会有详细讲解。

  1. var hello_01 = require('./module');
  2. hello_01.setName('wenlonghor');
  3.  
  4. var hello_02 = require('./module');
  5. hello_02.setName('HelloHor');
  6.  
  7. hello1.sayHello();

这时,输出结果:Hello HelloHor!

3:exports

Exports本身仅仅是一个普通的空对象{},本身咱们用来生命接口的,也相当于一个地址的引用。创建exports_test.js:

  1. function MyHello(){ //创建一个名为MyHello的对象
  2.    var name;
  3.    this.setName = function(myName){
  4.       name = myName;
  5.    }
  6.    this.sayHello = function(){
  7.       console.log('Hello '+ name + "!");
  8.    }
  9.    exports.Hello = MyHello; //创建了一个对外接口Hello,这个接口指向MyHello对象。

当我们需要使用MyHello对象的时候:

  1. var tmp = require('./export_test.js');
  2. var obj_MyHello = tmp.Hello;

这里是显示的把Hello用不同种方式明明,来方便区分的。第一行中tmp获取的仅仅是exports接口对象,第二行通过tmp.Hello来获取exports接口对外提供的Hello借口,这个接口指向MyHello对象。即把MyHello对象赋值给obj_MyHello。

开发指南中还指明了另外一种方法来对MyHell对象提供对外接口:

  1. function MyHello(){ //创建一个名为MyHello的对象
  2.    var name;
  3.    this.setName = function(myName){
  4.       name = myName;
  5.    }
  6.    this.sayHello = function(){
  7.       console.log('Hello '+ name + "!");
  8.    }
  9. module.exports = MyHello;

通过上述方式,我们在获取MyHello对象的方式可以简化为:

  1. var obj_MyHello = require('./exports_test.js');

具体的原理开发指南中所说的还不太明白,以后补上!

--------包-------

在讲包之前,先贴一个从npm中获取的express包,来看看包的结构:

从上述包结构并不是完全符合CommonJS的规范。这表明node对包的要求没有那么严格。只要这个包的根目录有package.json,并符合node对package.json的规范即可。接下来贴上express中package.json中的内容:

由于文件过长,只截取我们需要用到的内容即可。Main字段。上面章节已经提高过了,require()在引用的时候,可以不加拓展名。

Require('./xxx')。xxx如果是一个包,首先会检查包中的package.json中的main地段,将他作为包的接口模块,如果package.json不存在或者package.json中main字段不存在,会找当前包目根目录下的index.js或index.node作为包的接口。当然如果都没有找到,就会报异常了。。。

Package.json中dependencies:

这个是包的依赖关系,同样截取express的package.json中dependencies地段:

在这个字段中描述了express包中需要用到的相关第三方包。如果我们在安装express的时候npm会根据这个依赖关系添加到当前目录的node_modules中,也就是前面我们展示的express包结构截图。

Nodejs包管理器

在使用过nodejs的包管理器后发现比java中的要方便太多,相信用过sublimeText的也会有相同的经历,sublimeText的包管理器同nodejs的类似。

在讲包管理器之前需要先讲一个基础知识:本地模式和全局模式

  1. //npm [install/i] -g [package_name],全局模式
  2. npm install -g express
  3.  
  4. //npm [install/i] [package_name],本地模式
  5. npm install express

通过全局模式安装的node包会放在如下图的目录下

使用全局模式的需求时,不止一个项目会用到它,不用在各个项目里面都单独加入这个模块,减少了模块的副本数量。全局模式需要在系统的环境变量上注册PATH。

需要注意的的一点是:使用全局模式安装的包并不能直接在javascript中使用require()直接获得。这个会在模块与包深入部分讲解。

与全局模式对应的是本地模式,本地模式就是在命令行的当前目录创建node_modules目录并把模块放入这个目录里面:

当然,上图所示的模块没有意义,因为我们自己建立的包是在test、test02等文件夹下。放置的cmd.exe是为了说明命令行的执行目录特意放在当前目录用于说明用的。通常情况下,本地模式实用的目录为当前项目的根目录,也就是package.json的同一级目录下面:

使用npm install自动获取依赖包

前面讲解package.json中有一个字段dependencies字段。我们在写自己的项目中如果用到express,或者mongodb的时候,除了上述的本地模式和全局模式手动安装相应的express包和mongodb包。也可以在dependencies字段中注明,然后在package.json的当前目录执行命令行

  1. npm [install/i] [-g]

npm会自动解析dependencies字段中还没有的包,从npm的包管理中心(http://npmjs.org)搜索并下载包,安装在当前执行命令行的node_nodules子目录下。

Reference:

《Node.js开发指南》

深入浅出Node.js(三):深入Node.js的模块机制

http://blog.sina.com.cn/s/blog_9f1c093101015cbo.html

http://jin541223.blog.163.com/blog/static/1637398052012111122751840/ 

原文地址:https://www.cnblogs.com/wenlonghor/p/3307057.html