谈到组件,JavaScript是不具备这个特点的,以前JavaScript很多功能都依赖不同厂商的实现。基本在组件这个方面有如下特点:
.JavaScript没有模块系统。没有原生的支持密闭作用域或依赖管理。
.JavaScript没有标准库。核心库外,没有文件系统的API等,不过Html5规范出来后,这些将会有的:)。
.JavaScript没有标准API接口。
.JavaScript没有包管理系统。
当有了CommonJS(http://www.commonjs.org)规范的出现,其目标是为了构建JavaScript在包括Web服务器,桌面,命令行工具,及浏览器方面的生态系统。
CommonJS制定了解决这些问题的一些规范,而Node.js就是这些规范的一种实现。Node.js自身实现了require方法作为其引入模块的方法,同时NPM也基于CommonJS定义的包规范,实现了依赖管理和模块自动安装等功能。这里我们将深入一下Node.js的require机制和NPM基于包规范的应用。
一,Node.JS模块包管理:
1.编写及加载使用模块
在Node.JS中编写及安装一个js的模块是很简单的。
首先写编写一个test.js,内容如下:
exports.myfunc= function () {
console.log('hello,world');
};
也可以写成:
var myfunc = function () {
console.log('hello,world');
};
exports.myfunc = myfunc;
保存这个文件就可以在你的别的js代码里调用了,在这里我写一个app.js内容如下:
var test = require('./test.js');
console.log( 'test my function:\n ' + test.myfunc());
在node.js的命令行中运行:
node app.js
你会发现打印出:
test my function:
hello world
分析一下上述的行为,在你用node app.js时,有如下后台动作:
首先node 用module对象来加载你的app.js.
然后会把你的js内容进行封装调用。原来app.js内从变成如下内容:
(function (exports, require, module, __filename, __dirname) {
var test = require('./test.js');
console.log( 'test my function:\n ' + test.myfunc());
})
再进行执行。在执行到require('./test.js')时,会按着路径进行搜索test.js
而其实这个require方法实际调用的就是module对象的load方法。load方法在载入、编译、缓存了module后,返回module的exports对象。这就是test.js文件中只有定义在exports对象上的方法才能被外部调用的原因。
其实require加载模块有一个复杂的逻辑。
这里简单说一下,
第一种情况。当require中的参数为没有路径,没有文件后缀的一个字符串时比如require('httpd');
Node.JS搜索顺序如下:
a.从缓存中加载。b.从原生模块加载.c.从文件加载。从文件加载也有是很一个顺序:
Node.JS运行一个js程序比如刚才通过node app.js时,module加载时会形成一个当前的有效路径,这是一个路径集合。
首先是当前路径,然后是当前路径的父目录,再是父目录的父目录,只到根目录。
搜索模块首先从当前路径中的node_modules子目录去寻找,找不到就找这个目录中的package.json文件中的main参数指定的目录,然后就是父目录的node_modules子目录,一直找到根目录,再没找到。就找NODE_PATH中设定的目录下去寻找。
第二种情况:require参数是相对或绝对路径下的模块名比如 require('./test.js') 或者require('/home/joezhang/nodejs/test')这个不用搜索直接加载,因为有绝对路径麻:)
2.包的安装:
Node.JS中的包就是包装模块的东西。一般情况下我们可以安装一些包。用npm install来安装。npm install package-name这样安装的是Node.JS包资源库中的包你可通过如下命令来看这个资源库服务器
$npm config get registry
当然你也可以更改这个库$npm config set registry "myregistry.xxx.com" 我在另一篇博文里描述
其实你还可以从网络上下载包,解压后本地安装这个包
一般下载解压后的包是一个目录,这个目录确定有一个package.json文件存在。然后用如下命令安装:
npm install package-path 比如: npm install '/home/joezhang/program/mypkg'
mypkg目录下有一个符个CommonJS规范的package.json文件。
二,模块开发:
1.模块分类:
原生:
非原生:.js .node .json.
2.模块开发一般有两种,一种就是提到过的.js模块的开发,你也可以把这个js文件模块直接加载到你的项目,也可以先封装成包的格式,安装到你的Node.JS全局环境中进行使用。
js模块的开发,以前都提过。这里重点是讲一下C/C++第三方模块的开发与使用。
---未完待续----