Package Manager Tips 包管理技巧
The semantics of Node's require()
function were designed to be general enough to support a number of sane directory structures. Package manager programs such as dpkg
, rpm
, and npm
will hopefully find it possible to build native packages from Node modules without modification.
Node的require()
函数的语义被设计的足够通用化,以支持各种常规目录结构。包管理程序如 dpkg
,rpm
和npm
将不用修改就能够从Node模块构建本地包。
Below we give a suggested directory structure that could work:
接下来我们将给你一个可行的目录结构建议:
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.
假设我们希望将一个包的指定版本放在/usr/lib/node/<some-package>/<some-version>
目录中。
Packages can depend on one another. In order to install package foo
, you may have to install a specific version of package bar
. The bar
package may itself have dependencies, and in some cases, these dependencies may even collide or form cycles.
包可以依赖于其他包。为了安装包foo
,可能需要安装包bar
的一个指定版本。包bar
也可能有依赖关系,在一些情况下依赖关系可能发生冲突或形成循环。
Since Node looks up the realpath
of any modules it loads (that is, resolves symlinks), and then looks for their dependencies in the node_modules
folders as described above, this situation is very simple to resolve with the following architecture:
因为Node会查找它所加载的模块的真实路径
(也就是说会解析符号链接),然后按照上文描述的方式在node_modules
目录中寻找依赖关系,所以可以使用如下的目录结构解决这个问题:
/usr/lib/node/foo/1.2.3/
- Contents of thefoo
package, version 1.2.3./usr/lib/node/foo/1.2.3/
- 包foo
的1.2.3版本内容。/usr/lib/node/bar/4.3.2/
- Contents of thebar
package thatfoo
depends on./usr/lib/node/bar/4.3.2/
- 包foo
依赖的包bar
的内容。/usr/lib/node/foo/1.2.3/node_modules/bar
- Symbolic link to/usr/lib/node/bar/4.3.2/
./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/*
- Symbolic links to the packages thatbar
depends on./usr/lib/node/bar/4.3.2/node_modules/*
- 指向包bar
所依赖的包的符号链接。
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.
因此即便存在循环依赖或依赖冲突,每个模块还是可以获得他所依赖的包的一个可用版本。
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
.
当包foo
中的代码调用require('bar')
,将获得符号链接/usr/lib/node/foo/1.2.3/node_modules/bar
指向的版本。同样,当包bar
中的代码调用require('queue')
,降火的符号链接/usr/lib/node/bar/4.3.2/node_modules/quux
指向的版本。
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 will not bother looking for missing dependencies in /usr/node_modules
or /node_modules
.
为了进一步优化模块搜索过程,不要将包直接放在/usr/lib/node
目录中,而是将它们放在/usr/lib/node_modules/<name>/<version>
目录中。这样在依赖的包找不到的情况下,就不会一直寻找到/usr/node_modules
目录或/node_modules
目录中了。
In order to make modules available to the node 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.
为了使模块在node REPL中可用,你可能需要将/usr/lib/node_modules
目录加入到$NODE_PATH
环境变量中。由于在node_modules
目录中搜索模块使用的是相对路径,基于调用require()
的文件所在真实路径,因此包本身可以放在任何位置。
(转之手册)