Skip to main content

nodejs里的路径

绝对路径

absolute path,绝对路径,表示从根目录指定文件或目录的位置,绝对路径的表示形式总是以斜杠/开头,指向当前所在目录所在的系统盘的根目录

相对路径

relative path,相对路径,表示从当前目录出发寻找的同级目录或者上层目录,通常以./或者.//开头

  • .,表示当前目录
  • ..,表示上层目录
  • 如果前面不加任何点,仍然表示当前目录
D://
├─ other.js
├─ web
├─ dist
├─ favicon.ico
├─ index.html
└─ static
├─ css
│ ├─ main.css
├─ js
│ ├─ main.js
└─ images
└─ picture.jpg

以这样一个目录结构为例:

在 html 页面存在以下路径表示形式:

  • <script src="/other.js"></script>

  • <link rel="icon" href="favicon.ico">或者<link rel="icon" href="./favicon.ico">

  • <link rel="stylesheet" href="static/css/main.css">

  • <img src="static/images/picture.jpg">

在 CSS 中存在以下图片引入路径:

  • background-image: url("../images/picture.jpg")

node 中的路径解析规则

__dirname

__dirname就表示当前使用__dirname的文件的目录路径,例如webpack.config.js中使用__dirname,那就表示webpack.config.js所在的目录。

path.resolve

path.resolve([...paths])从右往左逐个解析每个路径片段,后面的每个 path 会被使用平台特定的分隔符追加到前面一个path的后面,直到构造出绝对路径就停止解析;如果在处理完所有给定的 path 片段之后还未生成绝对路径,则会使用当前工作目录。

例如:path.resolve('/目录1', '/目录2', '目录3')首先解析目录3,无法构造出绝对路径,然后追加到/目录2后面,由于/目录2是绝对路径,所以解析停止,返回/目录2/目录3

image-20200918181338076

path.join

path.join([...paths])将所有给定的 path 片段使用平台特定的分隔符作为定界符连接到一起,最后返回合成的路径字符串。

对于 windows 平台,分隔符就是反斜杠\,在 linux 平台分隔符是斜杠/

image-20200918164844514

path.join只负责连接路径并规范化(去除路径结尾的.或者/这样的分隔符),path.resolve构造成绝对路径后就会停止解析剩余的路径。

image-20200918180820475

require.resolve

require.resolve(request[, options])必须传入一个模块路径参数去解析,其它还可以传入用于解析模块的路径地址,如果存在,则使用这些路径而不是默认的解析路径。这些路径中的每一个都用作模块解析算法的起点,这意味着从该位置开始检查 node_modules 层次结构。

最终返回一个完整的解析后的规范的文件路径名。

image-20200918171525655

require.resolve内部会使用require()的查询机制,所以理解require.resolve首先要理解require()的机制。

nodejs 的文档解释了require()的规则,大致如下:

  • 在 nodejs 中每个文件都是一个模块,首先不可以使用require() 载入具有 .mjs 扩展名的文件

  • 如果传递给require()的是一个 nodejs 的核心模块名称,例如require("http"),则直接返回该模块

  • 如果传递给require()的不是核心模块名,也没有以/./../开头,那么 nodejs 会从当前模块所在目录的node_modules中查找模块,如果找不到就往上层父目录继续查找。例如在'/home/ry/projects/foo.js'中使用require("bar.js"),那么查找顺序如下:

    • /home/ry/projects/node_modules/bar.js
    • /home/ry/node_modules/bar.js
    • /home/node_modules/bar.js
    • /node_modules/bar.js
  • 如果按确切的文件名没有找到模块,则 Node.js 会尝试带上 .js.json.node 拓展名再加载

  • 如果是以/./../开头的模块名称,那么会按照路径查找规则

    • /指向根目录绝对路径,例如在d://home/ry/projects/foo.js'中调用require("bar.js"),那么会查找d://bar.js是否存在
    • ./相对于调用require()方法的模块自身的路径而言,例如在'/home/ry/projects/foo.js'中使用require("./bar.js"),则是在'/home/ry/projects中查找bar.js,也就是foo.jsbar.js是在同一目录下
    • ../则是查找上层的目录
  • 找不到模块就抛出MODULE_NOT_FOUND的错误

process.cwd

process.cwd是当前 NodeJS 命令工作的绝对路径,和__dirname的主要区别是__dirname是指向脚本命令所在文件的文件路径,随着程序执行,可能会发生变化,而process.cwd则不会在 NodeJS 程序执行过程中发生改变,也就是控制台当前显示的目录路径。

例如下面的文件结构:

-src
-lib
-index.js
-index.js

当在C:\\node\\temp目录下执行node src/index.js时,__dirname就是src的绝对路径,而process.cwd则是

C:\\node\\temp;如果src/index.js中执行lib/index.js,其内部__dirname则是lib的绝对路径。