此前一直保留着一个错误的认知:node执行的层级不同,但是执行相同一份脚本,结果是相同的。
然而实际上:在不同的目录层级下,执行相同的一份脚本,其结果不一定相同。它取决于你在这份脚本中,是否使用了一些相对路径;如果使用了相对路径,那么你可能要注意执行的位置。

一、错误示范

假设我们的文件夹目录结构是下面这样的:

├─ example
│ ├─ bat.js
│ └─ dir
│ ├─ server.js
│ └─ test.md

我们的 bat.js 内容

  1. const fs = require('fs')
  2. fs.readFile('./dir/test.md', 'utf-8', (err, data) => {
  3. console.log(err)
  4. if (err) return
  5. console.log('data', data)
  6. })
  • 执行方式一
  1. cd example
  2. node bat.js

结果:截屏2021-10-19 下午11.08.11.png

  • 执行方式二
  1. node example/bat.js

结果:截屏2021-10-19 下午11.12.39.png

二、结论 & 解决方案

显而易见的是,当我们的脚本使用了相对路径的时候;程序执行的结果与我们的层级是相关的。

但是,如同我们对需求文档的追求一样,我们希望需求是明确的,不希望对一份需求能够作出两种不同的解释。

所以,我们也希望我们程序的执行是完全如同我们所预期的,它不会因为执行环境的变化而产生不同。

解决方法是,我们使用绝对路径(如果使用了相对路径的,我们也想办法让它变成绝对路径)。

修改后的 bat.js与执行的效果

image-20211019233327805.png

三、其他node路径相关API

process.cwd() — 当前入口脚本的目录

在哪个位置执行脚本,则返回脚本所在的位置

bat.js

console.log(process.cwd())

image-20211019232315259.png

__dirname — 绝对路径,当前文件所在目录

__filename — 绝对路径,当前文件所在目录+文件本身

image-20211019234305585.png 可以发现,我们在不同的执行位置下,得出的结果是相同的。 很多时候,我们要的就是这种效果。

path.resolve — 用于拼接路径,最后得到绝对路径。

如果根据参数无法得到绝对路径,则会以当前执行路径为基础拼接。

通常我们配合 __dirname 使用,这样通常都能得到合理的绝对路径。

image-20211019234712238.png

可以看到,仅仅只凭 ‘,/‘ 来拼接绝对路径,还是不行的。我们需要一个绝对的路径帮我们定位。

path.join — 用于拼接路径,最后得到我们拼接的结果(未必是绝对路径,这也是它与path.resolve的根本区别)。

image-20211019235054366.png