require最常用的方法

require('http') 内置模块

require('./server')  “./”表示当前路径,后面跟的是相对路径
require("../lib/server") ../表示上一级目录,后面跟的也是相对路径

server.js

[javascript] 
var http = require('http'); 
function start(){ 
    server = http.createServer(function (req, res) {   
          res.writeHeader(200, {"Content-Type": "text/plain"});   
          res.end("Hello oschina\n");   
    })   
    server.listen(8000);   
    console.log("httpd start @8000");  

exports.start = start;

index.js

[javascript] 
//路径根据自己的实际情况而定 
var server = require("./learnNode/server"); 
server.start();

下面介绍require的只是来自于链接:http://www.nodecn.org/modules.html#file_Modules

模块
Node 使用 CommonJS 模块系统。

Node 有一个简单的模块加载系统。在 Node 中,文件和模块一一对应。比如,在 foo.js 加载同一目录中的circle.js 模块。

foo.js 的内容:

var circle = require('./circle.js');
console.log( 'The area of a circle of radius 4 is '
           + circle.area(4));
circle.js 的内容:

var PI = Math.PI;

exports.area = function (r) {
  return PI * r * r;
};

exports.circumference = function (r) {
  return 2 * PI * r;
};
模块 circle.js 导出了 area() 函数和 circumference() 函数,这样它们就能从模块外部访问了。要导出对象,将其添加到特殊的 exports 对象就行。

模块的局部变量是私有的。在本例中,变量 PI 是 circle.js 私有的。

核心模块
Node 有一些已编译成二进制的模块,这些模块将在本文档的其他地方详细 介绍。

核心模块在 Node 源代码的 lib/ 文件夹中定义。

使用 require() 时,核心模块总是优先加载。例如,require('http') 总是返回内置的 HTTP 模块,即使该名称的文件存在。

文件模块
如果没有找到确切的文件,Node 将尝试给所需的文件名 添加 .js 后缀再加载,然后再尝试 .node。

.js 文件被视为 JavaScript 文本文件,而 .node 文件被视为已编译的插件模块,用 dlopen 加载。

模块以 '/' 开头表示使用文件的绝对路径。例如,require('/home/marco/foo.js') 将加载/home/marco/foo.js 文件。

模块以 './' 开头表示调用 require() 时使用相对路径。也就是说,为了保证 require('./circle') 能找到,circle.js 必须和 foo.js 在同一目录。

如果不以 '/' 或'./' 开头,该模块可以是一个“核心模块”,也可是一个从 node_modules 文件夹中加载的模块。

从 `node_modules` 文件夹中加载
如果传递给 require() 有模块标识符是不是原生模块,而且不以 '/'、'../' 或'./' 开头,那么 Node 从当前模块的父目录+/node_modules 这个位置尝试加载。

如果还是没有找到,那么它跳到上层目录并依此类推,直到找到模块,或者达到根目录为止。

例如,如果在文件 '/home/ry/projects/foo.js' 中调用 require('bar.js'),那么 Node 将在下列位置查找,顺序如下:

/home/ry/projects/node_modules/bar.js
/home/ry/node_modules/bar.js
/home/node_modules/bar.js
/node_modules/bar.js
这就允许程序将依赖关系本地化,防止它们冲突。

优化 `node_modules` 查找过程

当嵌套依赖关系的层次很深时,这个文件查找列表可能会变得很长。因此,在查找时进行如下优化:

首先,/node_modules 不会附加到一个以 /node_modules 结尾的文件夹后面。

其次,如果调用 require() 的文件已经在一个 node_modules 层级里,那么最顶层的 node_modules 文件夹将被视为搜索树的根。

例如,如果在文件 '/home/ry/projects/foo/node_modules/bar/node_modules/baz/quux.js' 中调用require('asdf.js'),那么 Node 将搜索下列位置:

/home/ry/projects/foo/node_modules/bar/node_modules/baz/node_modules/asdf.js
/home/ry/projects/foo/node_modules/bar/node_modules/asdf.js
/home/ry/projects/foo/node_modules/asdf.js
以文件夹作为模块
Node 允许用户在独立的目录中方便地组织程序,然后提供单一入口指向该库。有三种方式可以将文件夹作为require() 的参数。

第一种方式是在该文件夹中创建 package.json 文件,指定一个 main 模块。一个典型的 package.json 文件可能看起来像这样:

{ "name" : "some-library",
  "main" : "./lib/some-library.js" }
如果此文件位于 ./some-library 文件夹,则 require('./some-library') 会尝试加载 ./some-library/lib/some-library.js。

这是 Node 能找到 package.json 文件的情况。

如果在该目录中没有 package.json 文件,那么 Node 将尝试加载该目录中的 index.js 或 index.node 文件。例如,如果上面的例子找不到 package.json,那么 require('./some-library') 将试图加载:

./some-library/index.js
./some-library/index.node
缓存

模块在首次被加载后会缓存起来。这意味着每次调用 require('foo') 将得到完全相同的对象,如果它被解析为同一个文件的话。

从 `require.paths` 加载

在 Node 中,require.paths 是一个字符串数组,表示模块不以 '/' './' 或 '..' 打头的搜索路径。例如,如果 require.paths 设置为:

[ '/home/micheil/.node_modules',
  '/usr/local/lib/node_modules' ]
则调用 require('bar/baz.js') 会搜索以下位置:

1: '/home/micheil/.node_modules/bar/baz.js'
2: '/usr/local/lib/node_modules/bar/baz.js'
可以在运行时修改 require.paths 数组来改变这种行为。

它的值最初从 NODE_PATH 环境变量而来,那是一个冒号分隔的绝对路径列表。在前面的例子中,NODE_PATH 环境变量可能被设置为:

/home/micheil/.node_modules:/usr/local/lib/node_modules
只有使用上面的 node_modules 算法找不到模块时才会尝试 require.paths。全局模块的优先级低于捆绑依赖。

**注意** 请不要修改 `require.paths`

出于兼容性的考虑,require.paths 仍然是模块查找过程的首选策略。尽管如此,它可能会在将来的版本中废弃。

虽然它看起来似乎是个好主意,但在实践中一个可变的 require.paths 列表往往是麻烦和混乱的根源。

修改 `require.paths` 毫无用处

这行代码并不会像期望的那样:

require.paths = [ '/usr/lib/node' ];
它的结果就是丢弃了 Node 实际的模块查找路径引用,并创建了一个毫无用处的指向别处的新的引用。

在 `require.paths` 中加入相对路径……不是个好主意

如果你这样做:

require.paths.push('./lib');
它不会添加 ./lib 在文件系统上已解析的完整路径。相反,它实际增加的是 './lib',这意味着如果你在/a/b/x.js 中 require('y.js'),那么它会查找 /a/b/lib/y.js。如果你之后又在 /l/m/n/o/p.js 中require('y.js'),那么它就会查找 /l/m/n/o/lib/y.js。

在实践中,人们往往将它作为捆绑依赖的临时解决办法,这个技巧是不太稳妥的。

零隔离

有一种糟糕的设计:所有模块共用一个 require.paths 数组。

结果,如果一个 Node 程序依赖于这种行为,它可能会永久而微妙地改变同一进程中其它 Node 程序的行为。当应用程序的复杂度增加时,我们倾向于封装功能,这些行为很难预料的部分会成为开发者的恶梦。

增编:软件包管理小贴示
在 Node 中,require() 函数的语义被设计成通用性足以支持大量合理的目录结构。因此 dpkg、rpm 和 npm之类的包管理器可以从 Node 模块构建原生包而不作更改。

下面我们给出一个可以工作的建议的目录结构:

比方说,我们希望 /usr/lib/node/<some-package>/<some-version> 文件夹中包含某个包的特定版本的内容。

一个软件包可以依赖别的包。为了安装 foo 包,你可能需要安装 bar 包的特定版本 。可能该 bar 包本身有依赖关系,在某些情况下,这些依赖关系甚至可能发生冲突或者形成回路。

由于 Node 在加载任何模块时都会查找它的真实路径(即:会解析符号链接),然后在 node_modules 文件夹用上文描述的方式查找依赖。使用以下架构可以很简单地解决:

/usr/lib/node/foo/1.2.3/ -foo 包的内容,版本1.2.3。
/usr/lib/node/bar/4.3.2/ -bar 包的内容,foo 依赖这个包。
/usr/lib/node/foo/1.2.3/node_modules/bar -到 /usr/lib/node/bar/4.3.2/ 的符号链接。
/usr/lib/node/bar/4.3.2/node_modules/* -到 bar 所依赖的包的符号链接。
因此,即使遇到一个回路,或者有依赖冲突,每个模块都能够得到它依赖的可用版本。

当 foo 包中有代码 require('bar') 时,它会得到符号链接至/usr/lib/node/foo/1.2.3/node_modules/bar 的版本。然后,当 bar 包调用 require('quux') 时,它会得到符号链接至 /usr/lib/node/bar/4.3.2/node_modules/quux 的版本。

此外,为了使模块查找过程更加优化,而 不是直接把包放到 /usr/lib/node 中,我们可以它们放到/usr/lib/node_modules/<name>/<version> 里。这样,Node 就不用在 /usr/node_modules 或/node_modules 中查找了。

为了使 REPL 能够正常引用模块,可以将 /usr/lib/node_modules 添加至 $NODE_PATH环境变量。因为使用node_modules 文件夹查找模块时的路径都是相对的,而且调用 require() 时基于文件的真实路径,因此软件包本身可以放在任何位置。

Node.js-require的使用方法的更多相关文章

  1. Node.js require 模块加载原理 All In One

    Node.js require 模块加载原理 All In One require 加载模块,搜索路径 "use strict"; /** * * @author xgqfrms ...

  2. Node.js require 方法

    Node.js 中存在 4 类模块(原生模块和3种文件模块),尽管 require 方法极其简单,但是内部的加载却是十分复杂的,其加载优先级也各自不同

  3. Node.js 手册查询-3-Mongoose 方法

    Mongoose 参考手册 标签(空格分隔): MongoDB Mongoose 是什么? 一般我们不直接用MongoDB的函数来操作MongoDB数据库 Mongose就是一套操作MongoDB数据 ...

  4. Node.js 手册查询-4-Express 方法

    express 标签(空格分隔): node.js express [TOC] 安装: 新版本中命令行工具分家了 npm install -g express //安装 express 然后 npm ...

  5. Node.js原生及Express方法实现注册登录原理

    由于本文只是实现其原理,所以没有使用数据库,只是在js里面模拟数据库,当然是种中还是需要用数据库的. 1.node.js原生方法 ①html页面,非常简单,没有一丝美化~我们叫它user.html & ...

  6. [Node.js] require背后的故事

    前言 熟悉Node.js的肯定对下面的代码熟悉 var http = require('http'); 这段代码很好理解,就是加载一个http模块.但是你有没有想过为什么要这么写?这其中的缘由是什么呢 ...

  7. node.js require() 源码解读

    时至今日,Node.js 的模块仓库 npmjs.com ,已经存放了15万个模块,其中绝大部分都是 CommonJS 格式.这种格式的核心就是 require 语句,模块通过它加载.学习 Node. ...

  8. 在CentOS 7上安装Node.js的4种方法(yum安装和源码安装)

    CentOS 7上的安装方法,其中涵盖了源码安装,已编译版本安装,EPEL(Extra Packages for Enterprise Linux)安装和通过NVM(Node version mana ...

  9. 在CentOS 7上安装Node.js的4种方法(包含npm)

    Node.js和Javascript有着千丝万缕的联系,可以说Node.js让Javascript显得从未如此强大.好吧…微魔其实是个门外汉…但是这并不能阻碍微魔学习探索未知的信心~今天在国外闲逛,看 ...

  10. 在CentOS 7上安装Node.js的4种方法

    一.源码安装 1.下载源码(官网查看最新版本链接) wget http://nodejs.org/dist/v0.10.30/node-v0.10.30.tar.gz 2.解压源码 tar xzvf ...

随机推荐

  1. map循环遍历删除

    typedef map<string,int> MapFileList; int main() { MapFileList m_SingleList; m_SingleList.inser ...

  2. 解决&nbsp在IE与firefox宽度不一致的问题

    浏览器默认不同的字体问题,字体分为“等宽”和“不等宽”字体,所以&nbsp在IE与firefox内间距是不等的.   解决办法:   body{font-family: 宋体, simsun; ...

  3. qt tablewidget中单个和批量删除代码如下(部分)截图如下

    def coltable(self):#行删除    row=self.downwidget.currentRow()    select=self.downwidget.isItemSelected ...

  4. 信息熵(Entropy)究竟是用来衡量什么的?

    信息熵(Entropy)究竟是用来衡量什么的? ——与Philip ZHANG商榷 思明 Philip ZHANG先生在反驳彭小明的时候,提出一个观点,他说:“ 就语言文 字来说,总体效率不是用民族主 ...

  5. MySQL server version for the right syntax to use near &#39;type=InnoDB&#39; at line 1

    转载请注明出处:http://blog.csdn.net/bettarwang/article/details/40180271 在执行一个Hibernate的演示样例时,配置了<propert ...

  6. 在Ubuntu上下载、编译和安装Android最新内核源代码(Linux Kernel)

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6564592 在前一篇文章提到,从源代码树下载下 ...

  7. React 入门最好的实例-TodoList

    React 的核心思想是:封装组件,各个组件维护自己的状态和 UI,当状态变更,自动重新渲染整个组件. 最近前端界闹的沸沸扬扬的技术当属react了,加上项目需要等等原因,自己也决定花些时间来好好认识 ...

  8. JavaScript学习笔记:检测数组方法

    检查数组的方法 很多时候我们需要对JavaScript中数据类型(Function.String.Number.Undefined.Boolean和Object)做判断.在JavaScript中提供了 ...

  9. document.write 向文档中写内容,包括文本、脚本、元素之类的,但是它在什么时候执行不会覆盖当前页面内容尼?

    当你打开一个页面,浏览器会 调用 document.open() 打开文档 document.write(...) 将下载到的网页内容写入文档 所有内容写完了,就调用 document.close() ...

  10. WebApi2官网学习记录---Configuring

    Configuration Settings WebAPI中的configuration settings定义在HttpConfiguration中.有一下成员: DependencyResolver ...