模块
require(函数)
- 用于在当前模块中加载和使用别的模块,传入一个模块名,返回一个模块导出对象。
- 模块名可使用相对路径(以./开头),或者是绝对路径(以/或C:之类的盘符开头;注意单个模块名默认指向node_modules文件)。
- 模块名中的.js扩展名可以省略。
- 可以加载和使用一个JSON文件。
exports(对象)
- 当前模块的导出对象,用于导出模块公有方法和属性。
- 别的模块通过require函数使用当前模块时得到的就是当前模块的exports对象。
module(对象)
- 通过module对象可以访问到当前模块的一些相关信息,但最多的用途是替换当前模块的导出对象。
- 如将模块导出对象改成一个函数
module.exports = function () {
console.log('Hello World!');
};
模块初始化
- NodeJS使用CMD模块系统
- 一个模块中的JS代码仅在模块第一次被使用时执行一次,并在执行过程中初始化模块的导出对象。之后,缓存起来的导出对象被重复利用。
var counter1 = require('./util/counter');
var counter2 = require('./util/counter');
//counter1和counter2是一样的
主模块
- 通过命令行参数传递给NodeJS以启动程序的模块被称为主模块。
- 主模块负责调度组成整个程序的其它模块完成工作
二进制模块
- 一般使用JS编写模块,但NodeJS也支持使用C/C++编写二进制模块。
- 编译好的二进制模块除了文件扩展名是.node外,和JS模块的使用方式相同。
模块路径解析规则
内置模块: 如果传递给
require
函数的是NodeJS内置模块名称,不做路径解析,直接返回内部模块的导出对象,例如require('fs')
。node_modules目录: NodeJS定义了一个特殊的
node_modules
目录用于存放模块。例如某个模块的绝对路径是/home/user/hello.js
,在该模块中使用require('foo/bar')
方式加载模块时,则NodeJS依次尝试使用以下路径。
/home/user/node_modules/foo/bar
/home/node_modules/foo/bar
/node_modules/foo/bar
- NODE_PATH环境变量: 与
PATH
环境变量类似,NodeJS允许通过NODE_PATH
环境变量来指定额外的模块搜索路径。NODE_PATH
环境变量中包含一到多个目录路径,路径之间在Linux下使用:分隔,在Windows下使用;分隔。例如定义了以下NODE_PATH
环境变量:
NODE_PATH=/home/user/lib:/home/lib
当使用require('foo/bar')
的方式加载模块时,则NodeJS依次尝试以下路径。
/home/user/lib/foo/bar
/home/lib/foo/bar
包(package)
index.js
- 如果在导入文件的时候没有指明文件名,默认加载index.js文件
//node/person/index.js
var head = require('./head');
var body = require('./body');
exports.create = function(name) {
return {
name: name,
head: head.create,
body: body.create
}
};
//node/main.js
var index = require('./lib');
这样将person看成一个包
- package.json
*如果cat文件夹中package.json文件这样定义,在之前的情况,就会优先加载main指定的文件;
{
"name": "cat",
"main": "./main"
}
命令行程序
- 在任何目录下都能像是一个命令行程序运行程序
Linux系统下设置(以路径/home/user/bin/node-echo.js
为例)
- 在shell脚本中,可以通过#!注释来指定当前脚本使用的解析器。所以首先在node-echo.js文件顶部增加以下一行注释,表明当前脚本使用NodeJS解析。
#! /usr/bin/env node
NodeJS会忽略掉位于JS模块首行的#!注释
- 然后,使用以下命令赋予node-echo.js文件执行权限。
$ chmod +x /home/user/bin/node-echo.js
- 最后,在PATH环境变量中指定的某个目录下,例如在/usr/local/bin下边创建一个软链文件,文件名与希望使用的终端命令同名,命令如下:
$ sudo ln -s /home/user/bin/node-echo.js /usr/local/bin/node-echo
这样处理后,就可以在任何目录下使用node-echo命令。
Windows设置
- 假设node-echo.js存放在C:\Users\user\bin目录,并且该目录已经添加到PATH环境变量里了。
*接下来需要在该目录下新建一个名为node-echo.cmd的文件,文件内容如下:
@node "C:\User\user\bin\node-echo.js" %*
工程目录
一个标准的工程目录
- /home/user/workspace/node-echo/ # 工程目录
- bin/ # 存放命令行相关代码
node-echo
+ doc/ # 存放文档
- lib/ # 存放API相关代码
echo.js
- node_modules/ # 存放三方包
+ argv/
+ tests/ # 存放测试用例
package.json # 元数据文件
README.md # 说明文件
NPM
同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的问题,常见的使用场景:
允许用户从NPM服务器下载别人编写的三方包到本地使用: npmjs.org包名搜索
允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用: 方法与三方包类似
允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用: 第一次使用NPM发布代码前需要注册一个账号。终端下运行
npm adduser
,之后按照提示做即可;
package.json的基本结构
{
"name": "node-echo", # 包名,在NPM服务器上须要保持唯一
"version": "1.0.0", # 当前版本号
"dependencies": { # 三方包依赖,需要指定包名和版本号
"argv": "0.0.2"
},
"main": "./lib/echo.js", # 入口模块位置
"bin" : {
"node-echo": "./bin/node-echo" # 命令行程序名和主模块位置
}
}
之后,就可以在package.json所在目录下运行npm publish
发布代码。
版本号: 语义版本号分为X.Y.Z三位,分别代表主版本号、次版本号和补丁版本号。当代码变更时,版本号按以下原则更新。
如果只是修复bug,需要更新Z位。
如果是新增了功能,但是向下兼容,需要更新Y位。
如果有大变动,向下不兼容,需要更新X位。
在申明三方包依赖时,除了可依赖于一个固定版本号外,还可依赖于某个范围的版本号。
其他命令
npm help <command>
可查看某条命令的详细帮助。在package.json所在目录下使用
npm install . -g
可先在本地安装当前命令行程序,可用于发布前的本地测试。npm update <package>
可以把当前目录下node_modules
子目录里边的对应模块更新至最新版本。使用
npm update <package> -g
可以把全局安装的对应命令行程序更新至最新版。使用
npm cache clear
可以清空NPM本地缓存,用于对付使用相同版本号发布新版本代码的人。使用
npm unpublish <package>@<version>
可以撤销发布自己发布过的某个版本代码。