解析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 相关文章推荐
jquery 分页控件实现代码
Nov 30 Javascript
location.search在客户端获取Url参数的方法
Jun 08 Javascript
Jquery给基本控件的取值、赋值示例
May 23 Javascript
jQuery中animate用法实例分析
Mar 09 Javascript
JS实现动态给图片添加边框的方法
Apr 01 Javascript
利用JQuery阻止事件冒泡
Dec 01 Javascript
js 获取html5的data属性实现方法
Jul 28 Javascript
vue中v-for加载本地静态图片方法
Mar 03 Javascript
JavaScript实现的反序列化json字符串操作示例
Jul 18 Javascript
对vuejs的v-for遍历、v-bind动态改变值、v-if进行判断的实例讲解
Aug 27 Javascript
node.js 使用 net 模块模拟 websocket 握手进行数据传递操作示例
Feb 11 Javascript
详解Vue的mixin策略
Nov 19 Vue.js
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
利用php来自动调用不同服务器上的flash
2006/10/09 PHP
PHP采集相关教程之一 CURL函数库
2010/02/15 PHP
php简单smarty入门程序实例
2015/06/11 PHP
PHP 信号管理知识整理汇总
2017/02/19 PHP
JavaScript入门教程(2) JS基础知识
2009/01/31 Javascript
通过javascript获取iframe里的值示例代码
2013/06/24 Javascript
js输入框邮箱自动提示功能代码实现
2013/12/10 Javascript
跟我学习javascript的undefined与null
2015/11/17 Javascript
JavaScript+html5 canvas绘制的小人效果
2016/01/27 Javascript
Js获取图片原始宽高的实现代码
2016/05/17 Javascript
JavaScript随机生成颜色的方法
2016/10/15 Javascript
ubuntu编译nodejs所需的软件并安装
2017/09/12 NodeJs
vue+element创建动态的form表单及动态生成表格的行和列
2019/05/20 Javascript
详解微信小程序支付流程与梳理
2019/07/16 Javascript
vue中created和mounted的区别浅析
2019/08/13 Javascript
JavaScript进阶(一)变量声明提升实例分析
2020/05/09 Javascript
js+cavans实现图片滑块验证
2020/09/29 Javascript
教你用Python写安卓游戏外挂
2018/01/11 Python
Python3解释器知识点总结
2019/02/19 Python
Python3.5文件修改操作实例分析
2019/05/01 Python
Django框架使用内置方法实现登录功能详解
2019/06/12 Python
对python中的os.getpid()和os.fork()函数详解
2019/08/08 Python
redis数据库及与python交互用法简单示例
2019/11/01 Python
keras得到每层的系数方式
2020/06/15 Python
详解Anaconda 的安装教程
2020/09/23 Python
Origins加拿大官网:雅诗兰黛集团高端植物护肤品牌
2017/11/19 全球购物
德国旅游网站:weg.de
2018/06/03 全球购物
墨西哥购物网站:Elektra
2020/01/21 全球购物
如何让Java程序执行效率更高
2014/06/25 面试题
优秀管理者获奖感言
2014/02/17 职场文书
综合测评个人总结
2015/03/03 职场文书
2016幼儿园中班开学寄语
2015/12/03 职场文书
创业计划书之闲置物品置换中心
2019/12/25 职场文书
python基于tkinter实现gif录屏功能
2021/05/19 Python
深入理解go slice结构
2021/09/15 Golang
Windows Server 版本 20H2 于 8 月 9 日停止支持,Win10 版本 21H1 将于 12 月结束支
2022/07/23 数码科技