模块路径解析规则

参考这篇博客

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

  1. 内置模块

    如果传递给require函数的是NodeJS内置模块名称,不做路径解析,直接返回内部模块的导出对象,例如require('fs')

  2. 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

可以看出module path的生成规则为:从当前文件目录开始查找node_modules目录;然后依次进入父目录,查找父目录下的node_modules目录;依次迭代,直到根目录下的node_modules目录。

  1. 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)

把多个子模块组成的大模块称为包

在组成一个包的所有子模块中,需要有一个入口模块,入口模块的导出对象被作为包的导出对象

在其它模块里使用包的时候,需要加载包的入口模块

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

首先搜索当前目录下的package.json文件,查找里面的mian属性,如果存在,则加载该属性所指定的的文件。 如果不存在package.json或者该文件里面没有main字段,nodejs将试图加载 index.js,都不存在那么就只有说一声Cannot find module了。

工程目录

了解了以上知识后,现在我们可以来完整地规划一个工程目录了。以编写一个命令行程序为例,一般我们会同时提供命令行模式和API模式两种使用方式,并且我们会借助三方包来编写代码。除了代码外,一个完整的程序也应该有自己的文档和测试用例。因此,一个标准的工程目录都看起来像下边这样。

- /home/user/workspace/node-echo/   # 工程目录
- bin/ # 存放命令行相关代码
node-echo
+ doc/ # 存放文档
- lib/ # 存放API相关代码
echo.js
- node_modules/ # 存放三方包
+ argv/
+ tests/ # 存放测试用例
package.json # 元数据文件
README.md # 说明文件

其中部分文件内容如下:

/* bin/node-echo */
var argv = require('argv'),
echo = require('../lib/echo');
console.log(echo(argv.join(' '))); /* lib/echo.js */
module.exports = function (message) {
return message;
}; /* package.json */
{
"name": "node-echo",
"main": "./lib/echo.js"
}

NPM

NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:

  • 允许用户从NPM服务器下载别人编写的三方包到本地使用。

  • 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。

  • 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。

nodejs系列笔记02---模块路径解析的更多相关文章

  1. seajs模块路径解析 简单总结

    最近在试着用 seajs + grunt 搭建项目雏形, 遇到的最大的问题就是 seajs 命名与调用, 简单总结一下. 模块调用 seajs中调用模块有两种方式,seajs.use(ID) . re ...

  2. 万恶技术系列笔记-jupyter工作路径和源文件打开方式

    万恶技术系列笔记-jupyter工作路径和源文件打开方式   脚本文件,ipynb的正确打开姿势: ipynb不能直接打开,需要复制到工作路径.例如 10_monkeys_model_1.ipynb ...

  3. NodeJS学习笔记 (24)本地路径处理-path(ok)

    模块概览 在nodejs中,path是个使用频率很高,但却让人又爱又恨的模块.部分因为文档说的不够清晰,部分因为接口的平台差异性. 将path的接口按照用途归类,仔细琢磨琢磨,也就没那么费解了. 获取 ...

  4. 【NodeJS 学习笔记02】入门资源很重要

    前言 在我映像中,异步最早出现与ajax,当时我还在搞.net,然后.net居然出了一个异步的控件...... 虽然我最后知道了他不是异步的......然后,前端异步用得特别多,如果不是异步的程序,你 ...

  5. nodejs系列笔记01---Buffer

    纯JavaScript无法处理二进制数据,buffer就是用来处理二进制数据的 原始数据保存在buffer实例中,一个buffer实例类似于数组.buffer的大小在建立时指定的不可更改. buffe ...

  6. mybatis系列笔记(3)---SqlMapConfig.xml解析

    SqlMapConfig.xml SqlMapConfig.xml是Mybatis的全局配置参数,关于他的具体用的有专门的MyBatis - API文档,这里面讲的非常清楚,所以我这里就挑几个讲下: ...

  7. 啃掉Hadoop系列笔记(02)-Hadoop运行环境搭建

    一.新增一个普通用户bigdata

  8. NodeJS学习笔记 (23)模块机制-module

    https://github.com/chyingp/nodejs-learning-guide

  9. [webpack]--webpack 如何解析代码模块路径

    前言 webpack是如何解析代码模块路径 webpack 中有一个很关键的模块 enhanced-resolve 就是处理依赖模块路径的解析的,这个模块可以说是 Node.js 那一套模块路径解析的 ...

随机推荐

  1. Android SDK目录结构介绍

    Android SDK目录下有很多文件夹,主要都是干什么的呢? 1. add-ons 这里面保存着附加库,比如Google Maps,当然你如果安装了Ophone SDK,这里也会有一些类库在里面. ...

  2. Java Jersey2使用总结

    原文  http://blog.segmentfault.com/lenbo_ma/1190000000495321 主题 Java 前言 在短信平台一期工作中,为便于移动平台的开发,使用了Java ...

  3. 整理mysql的28个知识点(转)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/weixin_39220472/article/details/80247011整理mysql28个知 ...

  4. vim编写Bash脚本

    vim编写Bash脚本,可以说是类unix系统下的原生应用啊,想到初vi编辑器可是每个unix自带的哦. 缩进:在.vimrc中添加 filetype plugin indent on 未完待续,以后 ...

  5. 最简短的openvpn的设置方式

    这种方式对于测试能否连接到远程系统,十分的有用.尤其是国内复杂的网络环境下,检测一下,到底是服务器的原因,还是网络因素造成的,这是一个快捷的方式. 需要注意的是:这种方法是用明文连接.所有的加密措施都 ...

  6. About - CONNECT_BY_FILTERING

    再次碰到一个诡异的事情,同样的SQL在两个类似数据库中执行时间相差非常之多.直观反应就是执行计划不一样,果不其然. 在跑得很快的环境中的执行计划, 但是在另外一个环境中的执行计划却是, 从执行计划中可 ...

  7. 【Android】第18章 位置服务和手机定位—本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-03-04 一.简介 目前,基于位置的服务发展迅速,已涉及到商务.医疗.定位.追踪.敏感区域警告.工作和生活等各个方面.定位服务融合了G ...

  8. 【Android】5.2 图像按钮和图片格式

    分类:C#.Android.VS2015: 创建日期:2016-02-07 一.简介 1.ImageBtton ImageBtton的用法和Button相似,也有Click事件,用法也和Button一 ...

  9. spring bean autowire自动装配

    转自:http://blog.csdn.net/xiao_jun_0820/article/details/7233139 autowire="byName"会自动装配属性与Bea ...

  10. DrawPrimitivesTest

    #ifndef _DRAW_PRIMITIVES_TEST_H_ #define _DRAW_PRIMITIVES_TEST_H_ ////----#include "cocos2d.h&q ...