Nodejs零起点开发-require的用法.docx_第1页
Nodejs零起点开发-require的用法.docx_第2页
Nodejs零起点开发-require的用法.docx_第3页
Nodejs零起点开发-require的用法.docx_第4页
Nodejs零起点开发-require的用法.docx_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Node.js零起点开发(二)-require的用法 require最常用的方法 require(http) 内置模块 require(./server) “./”表示当前路径,后面跟的是相对路径 require( ./lib/server ) ./表示上一级目录,后面跟的也是相对路径 server.js var http = require(http)function startserver = http.createServer(function (req, res) res.writeHeader(200, Content-Type : text/plain ) res.end( Hello oschinan ) ) server.listen(8000) console.log( httpd start 8000 ) exports.start = start index.js /路径根据自己的实际情况而定var server = require( ./learnNode/server )server.start 下面介绍require的只是来自于链接:/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.PIexports.area = function (r) return PI * r * rexports.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 时被载入的确切的文件名,使用 require.resolve 函数。 综上所述,这是 require.resolve 的伪码描述: require(X)1. If X is a core module, a. return the core module b. STOP2. If X begins with ./ or /, a. LOAD_AS_FILE(Y X) b. LOAD_AS_DIRECTORY(Y X)3. LOAD_NODE_MODULES(X, dirname(Y)4. THROW not found LOAD_AS_FILE(X)1. If X is a file, load X as JavaScript text. STOP2. If X.js is a file, load X.js as JavaScript text. STOP3. If X.node is a file, load X.node as binary addon. STOPLOAD_AS_DIRECTORY(X)1. If X/package.json is a file, a. Parse X/package.json, and look for main field. b. let M = X (json main field) c. LOAD_AS_FILE(M)2. LOAD_AS_FILE(X/index)LOAD_NODE_MODULES(X, START)1. let DIRS=NODE_MODULES_PATHS(START)2. for each DIR in DIRS: a. LOAD_AS_FILE(DIR/X) b. LOAD_AS_DIRECTORY(DIR/X)NODE_MODULES_PATHS(START)1. let PARTS = path split(START)2. let ROOT = index of first instance of node_modules in PARTS, or 03. let I = count of PARTS - 14. let DIRS = 5. while I ROOT, a. if PARTSI = node_modules CONTINUE c. DIR = path join(PARTS0 . I node_modules ) b. DIRS = DIRS DIR6. return DIRS 从 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 依赖这个包。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论