解析Node.js基于模块和包的代码部署方式


Posted in Javascript onFebruary 16, 2016

模块路径解析规则

有经验的 C 程序员在编写一个新程序时首先从 make 文件写起。同样的,使用 NodeJS 编写程序前,为了有个良好的开端,首先需要准备好代码的目录结构和部署方式,就如同修房子要先搭脚手架。本章将介绍与之相关的各种知识。

模块路径解析规则
我们已经知道,require函数支持斜杠(/)或盘符(C:)开头的绝对路径,也支持./开头的相对路径。但这两种路径在模块之间建立了强耦合关系,一旦某个模块文件的存放位置需要变更,使用该模块的其它模块的代码也需要跟着调整,变得牵一发动全身。因此,require函数支持第三种形式的路径,写法类似于foo/bar,并依次按照以下规则解析路径,直到找到模块位置。

内置模块

如果传递给 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

我们已经知道了 JS 模块的基本单位是单个 JS 文件,但复杂些的模块往往由多个子模块组成。为了便于管理和使用,我们可以把由多个子模块组成的大模块称做包,并把所有子模块放在同一个目录里。

在组成一个包的所有子模块中,需要有一个入口模块,入口模块的导出对象被作为包的导出对象。例如有以下目录结构。

- /home/user/lib/
  - cat/
    head.js
    body.js
    main.js

其中 cat 目录定义了一个包,其中包含了 3 个子模块。main.js 作为入口模块,其内容如下:

var head = require('./head');
var body = require('./body');

exports.create = function (name) {
  return {
    name: name,
    head: head.create(),
    body: body.create()
  };
};

在其它模块里使用包的时候,需要加载包的入口模块。接着上例,使用 require('/home/user/lib/cat/main')能达到目的,但是入口模块名称出现在路径里看上去不是个好主意。因此我们需要做点额外的工作,让包使用起来更像是单个模块。

index.js
当模块的文件名是 index.js,加载模块时可以使用模块所在目录的路径代替模块文件路径,因此接着上例,以下两条语句等价。

var cat = require('/home/user/lib/cat');
var cat = require('/home/user/lib/cat/index');

这样处理后,就只需要把包目录路径传递给 require 函数,感觉上整个目录被当作单个模块使用,更有整体感。

package.json
如果想自定义入口模块的文件名和存放位置,就需要在包目录下包含一个 package.json 文件,并在其中指定入口模块的路径。上例中的 cat 模块可以重构如下。

- /home/user/lib/
  - cat/
    + doc/
    - lib/
      head.js
      body.js
      main.js
    + tests/
    package.json

其中package.json内容如下。

{
  "name": "cat",
  "main": "./lib/main.js"
}

如此一来,就同样可以使用 require('/home/user/lib/cat')的方式加载模块。NodeJS 会根据包目录下的 package.json 找到入口模块所在位置。

Javascript 相关文章推荐
javascript EXCEL 操作类代码
Jul 30 Javascript
jquery 常用操作方法
Jan 28 Javascript
Prototype源码浅析 String部分(二)
Jan 16 Javascript
jQuery实现可收缩展开的级联菜单实例代码
Nov 27 Javascript
比较不错的JS/JQuery显示或隐藏文本的方法
Feb 13 Javascript
基于Angularjs实现分页功能
May 30 Javascript
javascript防篡改对象实例详解
Apr 10 Javascript
JavaScript实现封闭区域布尔运算的示例代码
Jun 25 Javascript
node.js读取Excel数据(下载图片)的方法示例
Aug 02 Javascript
jquery实现自定义树形表格的方法【自定义树形结构table】
Jul 12 jQuery
vue滚动tab跟随切换效果
Jun 29 Javascript
如何在Express4.x中愉快地使用async的方法
Nov 18 Javascript
javascript每日必学之基础入门
Feb 16 #Javascript
快速掌握Node.js环境的安装与运行方法
Feb 16 #Javascript
js实现异步循环实现代码
Feb 16 #Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(二)
Feb 16 #Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(一)
Feb 16 #Javascript
javascript HTML+CSS实现经典橙色导航菜单
Feb 16 #Javascript
JavaScript中使用数组方法汇总
Feb 16 #Javascript
You might like
phpMyadmin 用户权限中英对照
2010/04/02 PHP
基于php导出到Excel或CSV的详解(附utf8、gbk 编码转换)
2013/06/25 PHP
VB中的RasEnumConnections函数返回632错误解决方法
2014/07/29 PHP
2014年最新推荐的10款 PHP 开发框架
2014/08/01 PHP
php遍历树的常用方法汇总
2015/06/18 PHP
PHP的AES加密算法完整实例
2016/07/20 PHP
js刷新框架子页面的七种方法代码
2008/11/20 Javascript
JavaScript高级程序设计 错误处理与调试学习笔记
2011/09/10 Javascript
jquery创建表格(自动增加表格)代码分享
2013/12/25 Javascript
jquery高级编程的最佳实践详解
2014/03/23 Javascript
JS简单判断函数是否存在的方法
2017/02/13 Javascript
js is_valid_filename验证文件名的函数
2017/07/19 Javascript
Nodejs中使用phantom将html转为pdf或图片格式的方法
2017/09/18 NodeJs
微信小程序实现页面跳转传值的方法
2017/10/12 Javascript
JS实现DOM节点插入操作之子节点与兄弟节点插入操作示例
2018/07/30 Javascript
如何实现小程序tab栏下划线动画效果
2019/05/18 Javascript
vue.js实现三级菜单效果
2019/10/19 Javascript
微信小程序跨页面数据传递事件响应实现过程解析
2019/12/19 Javascript
详解Vue.js 响应接口
2020/07/04 Javascript
JSON 入门教程基础篇 json入门学习笔记
2020/09/22 Javascript
[00:33]2018DOTA2亚洲邀请赛TNC出场
2018/04/04 DOTA
Python类方法__init__和__del__构造、析构过程分析
2015/03/06 Python
分析Python中设计模式之Decorator装饰器模式的要点
2016/03/02 Python
Python统计python文件中代码,注释及空白对应的行数示例【测试可用】
2018/07/25 Python
pytorch 输出中间层特征的实例
2019/08/17 Python
一文轻松掌握python语言命名规范规则
2020/06/18 Python
Python基础教程之输入输出和运算符
2020/07/26 Python
英国儿童图书网站:Scholastic
2017/03/26 全球购物
SmartBuyGlasses美国官网:太阳眼镜和眼镜
2017/08/20 全球购物
香蕉共和国加拿大官网:Banana Republic加拿大
2018/08/06 全球购物
军训考核自我鉴定
2014/02/13 职场文书
《少年王勃》教学反思
2014/04/27 职场文书
经济类毕业生求职信
2014/06/26 职场文书
2014镇党委班子对照检查材料思想汇报
2014/09/23 职场文书
黄河绝恋观后感
2015/06/08 职场文书
2015年公路路政个人工作总结
2015/07/24 职场文书