软链、硬链对 Node.js 包寻找的影响

分别试了一下,记录一波。看黑字可以直接得到结论。

TLDR:

  • 硬链接会从链接到的位置开始查找依赖,而软链接会从文件原始位置开始查找依赖。
  • 软链可以将其他地方的目录增加到依赖查找路径中

对 Node.js 包寻找的影响

Linux 中可以使用ln命令对文件和目录在另一个位置建立一个同步的链接。

语法: ln [参数][源文件或目录][目标文件或目录]

参数和使用方式网上随便一搜就有很多,不详细说了。这里主要说一下我们通过ln命令将文件链接到别处后,Node.js 寻找包的行为是如何的。

我们搞这样一个目录:

01.png

a/index.js 中简单引用一下 node_modules 中的包。

02.png

当然如果现在执行node a/index.js是会报错的,找不到包。

接下来我们分别使用软链和硬链两种方式在 b 路径中创建两个链接。

1
2
ln -s ./a/index.js ./b/index-s.js
ln ./a/index.js ./b/index.js

b/index-s.js 是软链接,而 b/index.js 是硬链接。

分别执行一下试试:

03.png

04.png

会发现硬链接是可以找到依赖的,但是软链接不行。这是因为硬链接会从链接到的位置开始查找依赖,而软链接会从文件原始位置开始查找依赖。

软链依赖目录

如果我们将 b 目录下的 node_modules 软链到 a 目录下,那么 a/index.js 是否可以找到依赖呢?

执行ln -s -d /path/to/b/node_modules ./a,将 node_modules 软链到 a 目录下,会发现a/index.jsb/index-s.js都可以执行了。

05.png

说明软链可以将其他地方的目录增加到依赖查找路径中

区分硬链和软链

文件系统中,软链很容易区分,但是硬链就不容易区分了。

06.png

硬链接和源文件和目标文件是一样的,可以看一个文件的硬链接数:

07.png

可以使用ls -i来查找一个文件的 inode number

然后可以使用find -inum查找所有指向这个inode的文件:

08.png

发现 Node.js 有这样一个选项:–preserve-symlinks,可以设置成按照软链所在的位置查找依赖。不知道有没有坑。

父进程设置了–preserve-symlinks,默认是会传递给子进程的。

需要注意的是如果在创建子进程的时候设置了args,那么需要也把–preserve-symlinks加上。

1
child_process.fork'app.js', ['--preserve-symlinks']);