返回列表

转载:关于node.js的模块查找顺序(require.resolve())

默认分类 2014/11/06 05:28

原文地址:http://www.cnblogs.com/joyeecheung/p/3941705.html

关于node.js的模块查找顺序(require.resolve())

前几天社团群里有人问了阿里秋季前端笔试的一道题,想起来以前在官方文档看到过查找模块的算法,干脆自己写一写……

官方的require.resolve实现在这里. 因为我只是想看看查找过程,所以就直接把会被找的路径console.log出来看看而已。代码放在了我的github gist上:https://gist.github.com/joyeec9h3/74262a250b3e880c7fd4

结果如下:

---------------------------------------
        check /home/somebody/node_modules/othermodule
        check /home/somebody/node_modules/othermodule.js
        check /home/somebody/node_modules/othermodule.json
        check /home/somebody/node_modules/othermodule.node
---------------------------------------
if /home/somebody/node_modules/othermodule/package.json exists
        check /home/somebody/node_modules/othermodule/package.json[main]
---------------------------------------
if /home/somebody/node_modules/othermodule/index.js exists
        check /home/somebody/node_modules/othermodule/index.js
---------------------------------------
if /home/somebody/node_modules/othermodule/index.node exists
        check /home/somebody/node_modules/othermodule/index.node
---------------------------------------
        check /home/node_modules/othermodule
        check /home/node_modules/othermodule.js
        check /home/node_modules/othermodule.json
        check /home/node_modules/othermodule.node
---------------------------------------
if /home/node_modules/othermodule/package.json exists
        check /home/node_modules/othermodule/package.json[main]
---------------------------------------
if /home/node_modules/othermodule/index.js exists
        check /home/node_modules/othermodule/index.js
---------------------------------------
if /home/node_modules/othermodule/index.node exists
        check /home/node_modules/othermodule/index.node
---------------------------------------
        check /node_modules/othermodule
        check /node_modules/othermodule.js
        check /node_modules/othermodule.json
        check /node_modules/othermodule.node
---------------------------------------
if /node_modules/othermodule/package.json exists
        check /node_modules/othermodule/package.json[main]
---------------------------------------
if /node_modules/othermodule/index.js exists
        check /node_modules/othermodule/index.js
---------------------------------------
if /node_modules/othermodule/index.node exists
        check /node_modules/othermodule/index.node
---------------------------------------

for each $PATH in $NODE_PATH

---------------------------------------
if $PATH/package.json exists
        check $PATH/package.json[main]
---------------------------------------
if $PATH/index.js exists
        check $PATH/index.js
---------------------------------------
if $PATH/index.node exists
        check $PATH/index.node
---------------------------------------
if $HOME/.node_modules/package.json exists
        check $HOME/.node_modules/package.json[main]
---------------------------------------
if $HOME/.node_modules/index.js exists
        check $HOME/.node_modules/index.js
---------------------------------------
if $HOME/.node_modules/index.node exists
        check $HOME/.node_modules/index.node
---------------------------------------
if $HOME/.node_libraries/package.json exists
        check $HOME/.node_libraries/package.json[main]
---------------------------------------
if $HOME/.node_libraries/index.js exists
        check $HOME/.node_libraries/index.js
---------------------------------------
if $HOME/.node_libraries/index.node exists
        check $HOME/.node_libraries/index.node
---------------------------------------
if $PREFIX/lib/node/package.json exists
        check $PREFIX/lib/node/package.json[main]
---------------------------------------
if $PREFIX/lib/node/index.js exists
        check $PREFIX/lib/node/index.js
---------------------------------------
if $PREFIX/lib/node/index.node exists
        check $PREFIX/lib/node/index.node

 

简单来说,如果是require('x')这样开头不是相对or绝对地址符号, 尾巴也没说是.js或者.json的,就当做模块来找。先找是不是core module, 然后一级一级向上看node_modules文件夹,每一级的node_modules先看里面 是否有basename为所找的文件,再看是否有模块名文件夹下package.json的 main标明的文件,然后不死心地看看模块名文件夹下有没有index.js和 index.node。最后找不到的话,还要搜一遍全局环境, 比如$HOME/.node_modules/什么的。

实例如下:

  1. Node安装目录C:\Program Files odejs ode.exe

  2. 环境变量Path: C:\Program Files odejs\;

    C:\Users\username>npm install hui -g hui@0.0.6 C:\Users\username\AppData\Roaming pm ode_modules\hui

    cache: { C:\Users\username\1\1.js: Module children: Array[0] exports: Object filename: "C:\Users\username\1\1.js" id: "." loaded: true parent: null paths: Array[4] 0: "C:\Users\username\1 ode_modules" 1: "C:\Users\username ode_modules" 2: "C:\Users ode_modules" 3: "C: ode_modules" }, globalpaths: ["C:\Users\username\.node_modules", "C:\Users\username\.node_libraries", "C:\Program Files\lib ode"]

\=========================================================================== 转载:http://blog.csdn.net/chszs/article/details/8868086

Node.js的包概述

作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszs

在Node.js语言中,包和模块并没有本质的不同,包是在模块的基础上更深一步的抽象,包将某个独立的功能封装起来,用于发布、更新、依赖管理和进行版本控制。Node.js根据CommonJS规范实现了包机制,开发了npm来解决包的发布和获取需求。

Node.js的包是一个目录,其中包含JSON格式的包说明文件package.json。Node.js的包基本遵循CommonJS规范,因此具备以下特征:

CommonJS规范定义的包特性:

1)顶层目录包含package.json文件;
2)bin目录存放二进制文件;
3)lib目录存放JavaScript文件;
4)doc目录存放文档;
5)test目录存放单元测试。

Node.js的模块与文件是一一对应的,文件不仅可以是JavaScript源码文件或二进制文件,还可以是目录。最简单的包,就是一个目录的模块。

Node.js的包通常是一些模块的集合,在模块的基础上提供了更高层的抽象,相当于提供了一些固定接口的函数库。 通过定制package.json,我们可以创建更复杂、更完善、更符合规范的包用于发布。

Node.js在调用包时,首先会检查包中的package.json文件的main字段,将其作为包的接口模块,如果package.json文件的main字段不存在,那么Node.js会尝试寻找index.js或index.node作为包的接口。

package.json文件是CommonJS规范用于描述包的文件,完全符合规范的package.json文件应该包含以下字段:

1)name:包名。包名是唯一的,由小写字母、数字和下划线组成,不能含空格。
2)description:包说明。对包进行简要描述。
3)version:版本号。满足《语义化版本识别》规范的版本字符串。
4)keywords:关键字数组,通常用于搜索。
5)maintainers:维护者数组。每个元素包含name、email(可选)、web(可选)字段。
6)contributors:贡献者数组。格式与maintainer数组相同。包作者应该是贡献者数组的第一个元素。
7)bugs:提交bug的地址,可以是网址或电邮地址。
8)licenses:许可证数组。每个元素要包含type(许可证名称)和url(链接到许可证文本的地址)字段。
9)repositories:仓库托管地址数组。每个元素要包含type(仓库的类型,如Git)、url(仓库地址)和path(相对于仓库的路径,可选)字段。
10)dependencies:包依赖。是一个关联数组,由包名和版本号组成。

注:《语义化版本识别》规范是国外提出的一套版本命名规范,最初目的是解决各种各样的版本号大小比较的问题,目前被许多包管理系统所采用。

下面是一个完全符合CommonJS规范的package.json例子:

{   
  "name": "testpackage",  
  "description": "My package for CommonJS.",  
  "version": "0.1.0",  
  "keywords": [  
     "testpackage",  
     "liq"  
  ],   
  "maintainers": [  
     {  
        "name": "liq",  
        "email": "liq@hotmail.com",  
     }  
  ],  
  "contributors": [  
     {  
        "name": "liq",  
        "web": "http://blog.csdn.net/chszs"  
     }  
  ],  
  "bugs": {  
     "mail": "liq@hotmail.com",  
     "web": "http://blog.csdn.net/chszs"  
  },  
  "licenses": [  
     {  
        "type": "Apache License v2",  
        "url": "http://www.apache.org/licenses/apache2.html"  
     }  
  ],  
  "repositories": [  
     {  
        "type": "git",  
        "url": "http://github.com/chszs/packagetest.git"  
     }  
  ],  
  "dependencies": {   
     "webkit": "1.2",  
     "ssl": {   
        "gnutls": ["1.0", "2.0"],  
        "openssl": "0.9.8"  
     }  
  }  
}