您的位置:首页 >> LNMPA >> 和屌丝一起学Node.js—模块和包
和屌丝一起学Node.js—模块和包
[ 孤狼 | 2017-08-14 16:51:11 | LNMPA ]
声  明

本教程仅用于初学Node.js同学使用,内容由本人(孤狼)学习过程中笔记编写,本教程使用Node.js版本为6.11.1。本教程内容可以自由转载,但必须同时附带本声明,或注明出处。PAEA.CN版权所有。

上节我们了解了Node.js的异步运行方式,这节我们来认识一下Node.js里的模块和包.


模块,面向对象开发的基本理解.一个模块拥有一些功能.同时模块也是一些功能的集合.对应其他的语言中,模块可能对应的是类的概念.Node.js模块都是一个独立的js文件.里面封装了一下方法.唯一的不同是,Node.js里封装的方法可能是JS语言,也可能是C/C++语言.之前的HTTP服务器引用的http模块就是C++实现的.



创建模块


Node.js的模块就是一个文件,所以创建模块就是新建一个js文件即可.

这里我们创建一个名叫"people.js"的模块

如下:

var name;
var age;
var sex;
exports.setName = function(_name) {
  name = _name;
};
exports.getName = function() {
  return name;
};
exports.setAge = function(_age) {
  age = _age;
};
exports.getAge = function() {
  return age;
};
exports.setSex = function(_sex) {
  sex = _sex;
};
exports.getSex = function() {
  return name;
};

Node.js 提供了 exportsrequire两个对象,其中exports是模块公开的接口,require用于从外部获取一个模块的接口.


然后我们再创建一个文件,student.js,代码如下:

//引用people.js设置个zhangsan对象
var zhangsan=require("./people.js");
//赋予zhangsan属性值
zhangsan.setName("张三");
zhangsan.setAge("16");
zhangsan.setSex("男");
//调取zhangsan属性值
var name=zhangsan.getName();
//输出
console.log(name);

运行student.js

1.jpg

我们看到,这样一个初具功能的模块就做完了.


不同点,这里要格外注意的一件事是,Node.js 的模块只会调用一次,换句话说,不论引用多少次,都是一个对象.

例如:

var zhangsan=require("./people.js");
zhangsan.setName("张三");
var lisi=require("./people.js"); //等同于 var lisi=zhangsan;
lisi.setName("李四");
var name1=zhangsan.getName();
var name2=lisi.getName();
console.log(name1);
console.log(name2);


输出结果:

2.jpg


我们可以看出,不论是zhangsan还是lisi,对应的都是同一个对象.



覆盖 exports


有时候我们希望封装一个对象,例如:

//创建cn对象
function cn(){
	var word;
	this.setWord = function (_word) {
		word = _word;
	};
	this.getWord = function () {
		return word;
	};
}
module.exports = cn;

调用的代码例如:

var word=require('./word.js');
var zh=new word();
var jp=new word();
zh.setWord("中文");
jp.setWord("日文");
console.log(zh.getWord());
console.log(jp.getWord());

输出结果:

3.jpg

可以看到,这样就和我们以前认识的对象一样了.



多接口与单接口


有时候我们会用到不同数量的接口,当然,调用方式也不一样.

例如:多接口

//io.js
function io1(){
	this.out=function(){
		return "执行了io1";
	}
}
exports.Io1=io1;
function io2(){
	this.out=function(){
		return "执行了io2";
	}
}
exports.Io2=io2;

调用方法:

//ioaction.js
var Io1=require('./io').Io1;
var io1=new Io1();
console.log(io1.out());
var Io2=require('./io').Io2;
var io2=new Io2();
console.log(io2.out());

4.jpg

我们通过 require('文件').接口名; 来调用不同的接口.

如果我们只有一个接口,也可以使用这个方法,但是也可以使用另一个方法.

例如:单接口

//io.js
function io1(){
	this.out=function(){
		return "执行了io1";
	}
}
module.exports=io1;
//使用module.exports代替exports

调用方法:

//ioaction.js
var Io1=require('./io');
var io1=new Io1();
console.log(io1.out());

5.jpg

我们通过 require('文件'); 就可以获取到唯一接口.


TIP:module.exports和exports不能随意替换,他们并不是一个东西,exports只是一个和module.exports指向同一个对象的变量,当模块调用完毕之后,exports会自动释放,而module不会.所以只能使用module.exports来指定唯一接口



什么是包,包就是一堆模块的集合.

Node.js 的包是一个目录,其中包含一个 JSON 格式的包说明文件 package.json。严格符合 CommonJS 规范的包应该具备以下特征:

  1. package.json 必须在包的顶层目录下;

  2. 二进制文件应该在 bin 目录下;

  3. JavaScript 代码应该在 lib 目录下;

  4. 文档应该在 doc 目录下;

  5. 单元测试应该在 test 目录下。


Node.js 对包的要求并没有这么严格,只要顶层目录下有 package.json,并符合一些规范即可。当然为了提高兼容性,我们还是建议你在制作包的时候,严格遵守 CommonJS 规范。


比如我们创建一个模块,people.js把这个模块放到一个文件夹people/lib里.

//people.js
function C_people(){
	var name;
	var age;
	var sex;
	this.setName=function(_name){
		name=_name;
	}
	this.setAge=function(_age){
		age=_age;
	}
	this.setSex=function(_sex){
		sex=_sex;
	}
	this.getName=function(){
		return "ta叫"+name;
	}
	this.getAge=function(){
		return "ta今年"+age+"岁";
	}
	this.getSex=function(){
		return "ta是"+sex+"生";
	}
}
module.exports=C_people;


然后创建一个package.json文件在people文件夹里,注意,这里node.js通常会自动寻找main字段来当接口,如果找不到main,则会寻找index.jsindex.node作为包的接口.代码如下:

{
    "main": "./lib/people.js"
}


然后在people的文件夹外面创建一个调用文件one.js,代码如下:

//one.js
var Man=require('./people');
var laowang=new Man();
laowang.setName("老王");
console.log(laowang.getName());

运行结果如下.

6.jpg




包的管理


node.js的包管理使用npm,类似一个github.可以直接使用npm下载你需要的包文件,拓展业务功能及代码.有些时候,你只需要npm下来一些包,用一些简单的代码去调用这些包就能完成你想要的功能.例如,图片处理,视频处理,等等.这里就不再过多的赘述.

安装一个包:

#本地模式
npm [install/i] [package_name]
#全局模式
npm [install/i] -g [package_name]

例如:

npm install express

7.jpg

npm在默认情况下会从http://npmjs.org搜索或下载包,将包安装到当前目录的node_modules子目录下。这个过程你不用担心关联依赖问题,npm会自动解决关联依赖问题.

因为使用的是本地模式安装的,所以文件只会被下载到当前目录下,供当前项目使用.

如果采用的是全局模式安装npm 会将包安装到系统目录,这样就可以所有项目使用.

[注意:全局模式安装的包并不能直接在 JavaScript 文件中用require获得.]


全局链接,windows下就是快捷方式,上面说到,全局安装的包不能直接使用require获取.所以我们用全局链接的方式来链接进本地项目.

npm link 已经全局安装的包

例如:

npm link express

这样就会在你的项目下链接一个express,就能直接require来使用


[注意1:link在链接的时候会先判断是否已经全局安装了要链接的包,如果没有安装,则会先全局安装,然后再软链接到项目目录]


[注意2:link链接在linux系统下是软链接方式,在windows下是文件复制,虽然模式不一致,但是修改本地链接的文件,都会使全局文件同步修改,所以链接之后,除非必要不要修改,避免其他项目崩溃.]


如果想把本地的包链接到全局给其他项目使用,则先进入本地项目包目录,即package.json文件目录,然后运行npm link 本地包.这样本地包就会链接到全局.


本节代码下载:链接: https://pan.baidu.com/s/1jHHLaN8 密码: 7i29




转载请注明出处:http://gl.paea.cn/lnmpa/content/2017/08/14/109.html