我正在为 NodeJS 编写自己的包管理器。所有已安装的软件包都存储在
node-cache
文件夹中,如下所示:
node-cache/[email protected]
node-cache/[email protected]
将包命名为
package@version
非常重要,以便可以在缓存中存储多个版本。将包添加到 NodeJS 项目时,节点模块文件夹将包含指向缓存的符号链接,如下所示:
/node_modules/x
-> /node-cache/[email protected]
/node_modules/y
-> /node-cache/[email protected]
我得到了执行此操作的代码,并测试了以下情况:
// project/index.js
require("x");
/node-cache
和 project/node_modules
的结构如我上面所示的示例。我还让 [email protected]
执行 require("y")
,以确保包可以在缓存中正确地相互解析。
我还将环境变量
NODE_PATH
设置为 /node-cache
路径,以确保模块在缓存目录中解析,而不是在本地解析。运行 node index.js
时,[email protected]
加载得很好并已解决。但是 [email protected]
未解决,我收到此错误:
node:internal/modules/cjs/loader:1078
throw err;
^
Error: Cannot find module 'y'
Require stack:
- C:\Users\samal\AppData\Local\node-cache\[email protected]\index.js
- A:\Downloads\test\index.js
at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
at Module._load (node:internal/modules/cjs/loader:920:27)
at Module.require (node:internal/modules/cjs/loader:1141:19)
at require (node:internal/modules/cjs/helpers:110:18)
at Object.<anonymous> (C:\Users\samal\AppData\Local\node-cache\[email protected]\index.js:1:11)
at Module._compile (node:internal/modules/cjs/loader:1254:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
at Module.load (node:internal/modules/cjs/loader:1117:32)
at Module._load (node:internal/modules/cjs/loader:958:12)
at Module.require (node:internal/modules/cjs/loader:1141:19) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'C:\\Users\\samal\\AppData\\Local\\node-cache\\[email protected]\\index.js',
'A:\\Downloads\\test\\index.js'
]
}
发生这种情况是因为我的缓存文件被命名为
package@version
而不是仅仅 package
,我需要缓存同一包的多个版本。节点正在搜索 /node-cache/y
,因为 require()
被 [email protected]
搜索,但是只有一个 /node-cache/[email protected]
。删除 NODE_PATH
环境变量会产生相同的错误。
我想知道,最好的解决方案是什么,而不强迫用户做任何额外的不必要的工作来让包管理器工作,同时保持其快速的速度,并使用符号链接或任何不需要文件系统副本的东西?
解决办法其实很简单。解决方案是使用 --preserve-symlinks 标志。例如
node --preserve-symlinks index.js
。
这确保了符号链接在本地解析,而不是在缓存中,这就是它的工作原理。