包管理器提示
¥Package manager tips
Node.js require()
函数的语义被设计为足够通用以支持合理的目录结构。诸如 dpkg
、rpm
和 npm
之类的包管理器程序有望发现无需修改即可从 Node.js 模块构建原生包。
¥The semantics of the Node.js require()
function were designed to be general
enough to support reasonable directory structures. Package manager programs
such as dpkg
, rpm
, and npm
will hopefully find it possible to build
native packages from Node.js modules without modification.
下面,我们给出了一个可行的建议目录结构:
¥In the following, we give a suggested directory structure that could work:
假设想让位于 /usr/lib/node/<some-package>/<some-version>
的文件夹保存特定版本包的内容。
¥Let's say that we wanted to have the folder at
/usr/lib/node/<some-package>/<some-version>
hold the contents of a
specific version of a package.
包可以相互依赖。为了安装包 foo
,可能需要安装包 bar
的特定版本。bar
包本身可能存在依赖,在某些情况下,这些甚至可能发生冲突或形成循环依赖。
¥Packages can depend on one another. In order to install package foo
, it
may be necessary to install a specific version of package bar
. The bar
package may itself have dependencies, and in some cases, these may even collide
or form cyclic dependencies.
因为 Node.js 查找它加载的任何模块的 realpath
(即它解析符号链接)然后是 在 node_modules
文件夹中查找它们的依赖,这种情况可以通过以下架构解决:
¥Because Node.js looks up the realpath
of any modules it loads (that is, it
resolves symlinks) and then looks for their dependencies in node_modules
folders,
this situation can be resolved with the following architecture:
-
/usr/lib/node/foo/1.2.3/
:foo
包的内容,版本 1.2.3。¥
/usr/lib/node/foo/1.2.3/
: Contents of thefoo
package, version 1.2.3. -
/usr/lib/node/bar/4.3.2/
:foo
依赖的bar
包的内容。¥
/usr/lib/node/bar/4.3.2/
: Contents of thebar
package thatfoo
depends on. -
/usr/lib/node/foo/1.2.3/node_modules/bar
:/usr/lib/node/bar/4.3.2/
的符号链接。¥
/usr/lib/node/foo/1.2.3/node_modules/bar
: Symbolic link to/usr/lib/node/bar/4.3.2/
. -
/usr/lib/node/bar/4.3.2/node_modules/*
:bar
依赖的包的符号链接。¥
/usr/lib/node/bar/4.3.2/node_modules/*
: Symbolic links to the packages thatbar
depends on.
因此,即使遇到循环,或者如果存在依赖冲突,每个模块都将能够获得它可以使用的依赖版本。
¥Thus, even if a cycle is encountered, or if there are dependency conflicts, every module will be able to get a version of its dependency that it can use.
当 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
的版本。
¥When the code in the foo
package does require('bar')
, it will get the
version that is symlinked into /usr/lib/node/foo/1.2.3/node_modules/bar
.
Then, when the code in the bar
package calls require('quux')
, it'll get
the version that is symlinked into
/usr/lib/node/bar/4.3.2/node_modules/quux
.
此外,为了使模块查找过程更加优化,与其将包直接放在 /usr/lib/node
中,还可以将它们放在 /usr/lib/node_modules/<name>/<version>
中。这样 Node.js 就不会费心寻找 /usr/node_modules
或 /node_modules
中缺失的依赖了。
¥Furthermore, to make the module lookup process even more optimal, rather
than putting packages directly in /usr/lib/node
, we could put them in
/usr/lib/node_modules/<name>/<version>
. Then Node.js will not bother
looking for missing dependencies in /usr/node_modules
or /node_modules
.
为了使模块可用于 Node.js 交互式解释器,将 /usr/lib/node_modules
文件夹添加到 $NODE_PATH
环境变量可能会很有用。由于使用 node_modules
文件夹的模块查找都是相对的,并且基于调用 require()
的文件的真实路径,因此包本身可以位于任何位置。
¥In order to make modules available to the Node.js REPL, it might be useful to
also add the /usr/lib/node_modules
folder to the $NODE_PATH
environment
variable. Since the module lookups using node_modules
folders are all
relative, and based on the real path of the files making the calls to
require()
, the packages themselves can be anywhere.