Node.js的__dirname,__filename,process.cwd(),./的一些坑

栏目: Node.js · 发布时间: 6年前

内容简介:原文收录在我的 GitHub博客 (最近在学习我纳闷的很半天,我明明就是读取当前目录下的

原文收录在我的 GitHub博客 ( https://github.com/jawil/blog ) ,喜欢的可以关注最新动态,大家一起多交流学习,共同进步,以学习者的身份写博客,记录点滴。

最近在学习 Node.js 里面的 fs 模块,遇到了一个比较诡异的现象,踩到了坑,就是读取当前目录下的一个文件,死活读取不到,由于之前对于 Node.js 里面的 path 模块也不太熟悉,也没系统研究过,所以今天就踩了这个坑,记录踩坑的过程,防止以后踩坑和大家也踩坑。

说一下当时的情形:

Node.js的__dirname,__filename,process.cwd(),./的一些坑

我纳闷的很半天,我明明就是读取当前目录下的 1.findLargest.js ,为什么提示找不到这个文件,运行了几遍,死活找不到 1.findLargest.js 这个文件。

后来才发现是因为运行这个文件不是从当前目录运行了,从图中可以看出,当前的目录是 /Users/jawil/Desktop/nodejs/demo/ES6-lottery/syntax/nodejs ,而我运行这个脚本的目录是 /Users/jawil/Desktop/nodejs/demo/ES6-lottery ;这就是问题的所在了。不过为什么运行脚本的位置也会影响这个路径呢,且往下看。

探索

计算机不会欺骗人,一切按照规则执行,说找不到这个文件,那肯定就是真的找不到,至于为什么找不到,那就是因为我们理解有偏差,我最初理解的’./‘是当前执行 js 文件所在的文件夹的绝对路径,然后 Node.js 的理解却不是这样的,我们慢慢往下看。

Node.js 中的文件路径大概有 __dirname , __filename , process.cwd() , ./ 或者 ../ ,前三个都是绝对路径,为了便于比较, ./../ 我们通过 path.resolve('./') 来转换为绝对路径。

简单说一下这几个路径的意思:

__dirname:    获得当前执行文件所在目录的完整目录名
__filename:   获得当前执行文件的带有完整绝对路径的文件名
process.cwd():获得当前执行node命令时候的文件夹目录名 
./:           文件所在目录

先看一看我电脑当前的目录结构:

syntax/
    -nodejs/
        -1.findLargest.js
        -2.path.js
        -3.fs.js
    -regs
        -regx.js
        -test.txt

在 path.js 里面我们写这些代码,看看输出是什么:

const path = require('path')
console.log('__dirname:', __dirname)
console.log('__filename:', __filename)
console.log('process.cwd():', process.cwd())
console.log('./:', path.resolve('./'))

在当前目录下也就是 nodejs 目录运行 node path.js ,我们看看输出结果:

__dirname:     /Users/jawil/Desktop/nodejs/demo/ES6-lottery/syntax/nodejs
__filename:    /Users/jawil/Desktop/nodejs/demo/ES6-lottery/syntax/nodejs/2.path.js
process.cwd(): /Users/jawil/Desktop/nodejs/demo/ES6-lottery/syntax/nodejs
./:            /Users/jawil/Desktop/nodejs/demo/ES6-lottery/syntax/nodejs

Node.js的__dirname,__filename,process.cwd(),./的一些坑

然后在 项目根目录ES6-lottery 目录下运行 node syntax/nodejs/2.path.js ,我们再来看看输出结果:

__dirname:     /Users/jawil/Desktop/nodejs/demo/ES6-lottery/syntax/nodejs
__filename:    /Users/jawil/Desktop/nodejs/demo/ES6-lottery/syntax/nodejs/2.path.js
process.cwd(): /Users/jawil/Desktop/nodejs/demo/ES6-lottery
./:            /Users/jawil/Desktop/nodejs/demo/ES6-lottery

Node.js的__dirname,__filename,process.cwd(),./的一些坑

答案显而易见?我们可以通过上面的例子对比,暂时得出表面的结论:

  • __dirname: 总是返回被执行的 js 所在文件夹的绝对路径
  • __filename: 总是返回被执行的 js 的绝对路径
  • process.cwd(): 总是返回运行 node 命令时所在的文件夹的绝对路径
  • ./: 跟 process.cwd() 一样,返回 node 命令时所在的文件夹的绝对路径

但是,我们再来看看这个例子,我们在上面的例子加几句代码,然后:

我们在 1.findLargest.js 先加这句代码

exports.A = 1;

再来在刚才报错的 3.fs.js 里面加这两句代码看看:

const test = require(‘./1.findLargest.js’);

console.log(test)

运行 node syntax/nodejs/3.fs.js ,最后看看结果:

Node.js的__dirname,__filename,process.cwd(),./的一些坑

再次疑惑

为什么都是读取 ./1.findLargest.js 文件,一样的路径,为什么 require 能获取到,而 readFile 读取不到呢?

于是查了不少资料,看到了一些关于 require 引入模块的机制,从中学到了不少,也明白了为什么是这样。

我们先了解一下 require() 的基本用法:

下面的内容来自 require() 源码解读 ,由阮一峰翻译自《Node使用手册》。

Node.js的__dirname,__filename,process.cwd(),./的一些坑

我们从第(2)小条的a部分可以看出:

(2)如果 X 以 "./" 或者 "/" 或者 "../" 开头 
  a. 根据 X 所在的父模块,确定 X 的绝对路径。
  b. 将 X 当成文件,依次查找下面文件,只要其中有一个存在,就返回该文件,不再继续执行。

const test = require('./1.findLargest.js') 按照上面规则翻译一遍就是:

  1. 根据 1.findLargest.js 所在的父模块,确定 1.findLargest.js 的绝对路径为 /Users/jawil/Desktop/nodejs/demo/ES6-lottery/syntax/nodejs ,关于其中的寻找细节这里不做探讨。

  2. 先把 1.findLargest.js 当成文件,依次查找当前目录下的 1.findLargest.js ,找到了,就返回该文件,不再继续执行。

根据 require 的基本规则,对于上面出现的情形也就不足为奇了,更多 require 的机制和源码解读,请移步:

require() 源码解读

那么关于 ./ 正确的结论是:

require() 中使用是跟 __dirname 的效果相同,不会因为启动脚本的目录不一样而改变,在其他情况下跟 process.cwd() 效果相同,是相对于启动脚本所在目录的路径。

总结:

  • __dirname: 获得当前执行文件所在目录的完整目录名
  • __filename: 获得当前执行文件的带有完整绝对路径的文件名
  • process.cwd():获得当前执行node命令时候的文件夹目录名
  • ./: 不使用require时候,./与process.cwd()一样,使用require时候,与__dirname一样

只有在 require() 时才使用相对路径 (./, ../) 的写法,其他地方一律使用绝对路径,如下:

// 当前目录下
 path.dirname(__filename) + '/path.js'; 
// 相邻目录下
 path.resolve(__dirname, '../regx/regx.js');

最后看看改过之后的结果,不会报错找不到文件了,不管在哪里执行这个脚本文件,都不会出错了,防止以后踩坑。

Node.js的__dirname,__filename,process.cwd(),./的一些坑


以上所述就是小编给大家介绍的《Node.js的__dirname,__filename,process.cwd(),./的一些坑》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

网站转换率优化之道

网站转换率优化之道

[美] Khalid Saleh、[美] Ayat Shukairy / 顾 毅 / 人民邮电出版社 / 2012-4 / 45.00元

内容简介: 怎样才能将访问者转化为顾客? 本书提供了一些切实可行的建议,比如如何说服访问者作出购买决定,如何避免用户因信息过量或导航繁琐而离开网站等。不论你是在设计或营销大型电子商务网站,还是在管理中小型在线业务,都可以从本书学会怎样使用市场营销原则、设计方法、可用性原则和分析数据来持续提升网站的转换率。 作者帮助过众多公司吸引在线顾客,有着丰富的实战经验,在书中细致讨论了从访问......一起来看看 《网站转换率优化之道》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

html转js在线工具
html转js在线工具

html转js在线工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具