快速上手 - 模块

  • 作者:KK

  • 发表日期:2017.9.12


如果你玩过前端的 RequireJs 或者 SeaJs 就会更快速理解了,差不多的。

文件就是模块

建 a.js 和 b.js 两个文件,a的代码如下:

var b = require('./b');
console.log(b.getAge());

b的代码如下:

module.exports = {
	getAge : function(){
		return 99 + 10;
	}
};

执行node a.js则输出 109 对吧。

很明显在a里引入了b文件,而且引入的时候不需要写.js这个后缀,而b文件里则是返回一个模块给a,怎么返回模块呢?向module.exports赋值就行了,最终的目标是想方设法让 module.exports 这个东西成为一个对象,有方法有属性,然后就能将这个模块返回给引用的js去用了。


被require的文件可以不定义模块

b.js 其实也可以只执行自己的代码而不设定 module.exports,这样就像 PHP 一样只是两个文件之间 require 运行而已。


模块目录

在项目目录下建一个 node_modules 目录,把上面的 b.js 放进去,然后 a.js 就可以这样写了:

var b = require('b');
console.log(b.getAge());

也就是require函数不需要声明当前目录,直接写模块名称名字就可以,node 会自动去 node_modules 目录查找模块名称对应的文件名,而下面的其它模块类型我都默认基于 node_modules 目录部署的哦。


目录也是模块

基于上面的例子,在 node_modules 目录下建一个 c 目录,里面建个 index.js 代码如下:

module.exports = function(name){
	this.name = name;
	this.say = function(){
		return 'I am ' + this.name;
	};
};

然后 a.js 代码改成这样:

var c = require('c');
var x = new c('kk');
console.log(x.say());

这里 a.js 引入的时候只是写了 c,系统引入时发现 node_modules/c 是一个目录,所以会自动找c目录里面的 index.js 作为入口文件。

其中 index.js 也可以 require 同目录下的其它文件来完成自己的所有逻辑组织。

目录模块里面也可以嵌套node_modules:

为了快速了解这个我建议你在测试目录下执行npm install unzip命令,会从网上下载安装这个 unzip 模块,看到产生 node_modules/unzip 目录后(还有更多其它目录),进里面你会发现还有一层 node_modules ,里面会有个readable-stream模块(node_modules/unzip/node_modules/readable-stream)。

这是因为 unzip 这个模块引用了其它的模块来完善自己的功能代码,而外面 unzip 同级的更多目录也是它引用的模块,而你自己写的模块也可以这么嵌套。


二进制模块

听说还有一种是二进制模块,后缀名是.node,我还没接触过,它是经由C/C++编写的扩展。


原生模块

有些模块是 node 平台自带的,我们不需要定义,直接 require 就可以用,比如:

var path = require('path');	//引入node自带的path模块
console.log('filename: ' + path.basename(__filename));	//当前文件名:test.js
console.log('extname: ' + path.extname(__filename));

其实原生模块也是一种二进制模块,但你并不能从 node 安装文件夹里找到类似 “path.node” 这样的原生模块文件,其实它们都被编译到了 node 命令里了,你可以注意一下比如 Windows 下的 node.exe 的容量达到 15M 左右。


第三方模块

后面将通过《npm 包管理器》介绍具体如何下载安装、使用和管理第三方模块,本质上第三方模块也是目录模块,就是一堆js文件封装在一个目录里让你去 require。