-
Notifications
You must be signed in to change notification settings - Fork 837
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Node.js的__dirname,__filename,process.cwd(),./的一些坑 #18
Comments
沙发 |
require是编译时执行,read是运行时执行,所以才会有差异吧,这个不是坑,只是你不懂而已。 |
|
mark |
@owen-carter 能细说下为什么编译时与运行时的不同吗?求教! |
各种路径的区别写得很清楚了,不过这个不算坑,补充一点,js 文件如果是符号链接, __dirname 指向的是实际js 文件所在目录, 查找 node_modules 时也会从实际文件所在目录下查找 |
@owen-carter 大哥,你确定require是编译执行么?我循环写个require(),不是就报错了?那是不是说明require是运行时?而不是编译阶段?你确定你懂? |
@jawil require 解读那张图片 加载不全 |
谢谢前辈的总结,按照前辈的面试经历慢慢补基础!共勉! |
赞赞赞 |
学习了 |
mark |
图片大量失效 |
import命令是编译阶段执行的,在代码运行之前。因此这意味着被导入的模块会先运行,而导入模块的文件会后执行。 |
请问 vscode 配色主题是什么?:) |
图片失效了,博文还在维护吗? |
? |
大哥,require是运行时 |
起因
原文收录在我的 GitHub博客 (https://github.com/jawil/blog) ,喜欢的可以关注最新动态,大家一起多交流学习,共同进步,以学习者的身份写博客,记录点滴。
最近在学习
Node.js
里面的fs
模块,遇到了一个比较诡异的现象,踩到了坑,就是读取当前目录下的一个文件,死活读取不到,由于之前对于Node.js
里面的path
模块也不太熟悉,也没系统研究过,所以今天就踩了这个坑,记录踩坑的过程,防止以后踩坑和大家也踩坑。说一下当时的情形:

我纳闷的很半天,我明明就是读取当前目录下的
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('./')
来转换为绝对路径。简单说一下这几个路径的意思,:
先看一看我电脑当前的目录结构:
在 path.js 里面我们写这些代码,看看输出是什么:
在当前目录下也就是
nodejs
目录运行node path.js
,我们看看输出结果:然后在
项目根目录ES6-lottery
目录下运行node syntax/nodejs/2.path.js
,我们再来看看输出结果:答案显而易见?我们可以通过上面的例子对比,暂时得出表面的结论:
但是,我们再来看看这个例子,我们在上面的例子加几句代码,然后:
我们在
1.findLargest.js
先加这句代码再来在刚才报错的
3.fs.js
里面加这两句代码看看:运行
node syntax/nodejs/3.fs.js
,最后看看结果:再次疑惑
为什么都是读取
./1.findLargest.js
文件,一样的路径,为什么require
能获取到,而readFile
读取不到呢?于是查了不少资料,看到了一些关于
require
引入模块的机制,从中学到了不少,也明白了为什么是这样。我们先了解一下
require()
的基本用法:下面的内容来自require() 源码解读,由阮一峰翻译自《Node使用手册》。
我们从第(2)小条的a部分可以看出:
const test = require('./1.findLargest.js')
按照上面规则翻译一遍就是:根据
1.findLargest.js
所在的父模块,确定1.findLargest.js
的绝对路径为/Users/jawil/Desktop/nodejs/demo/ES6-lottery/syntax/nodejs
,关于其中的寻找细节这里不做探讨。先把
1.findLargest.js
当成文件,依次查找当前目录下的1.findLargest.js
,找到了,就返回该文件,不再继续执行。根据
require
的基本规则,对于上面出现的情形也就不足为奇了,更多require
的机制和源码解读,请移步:require() 源码解读。
那么关于
./
正确的结论是:在
require()
中使用是跟__dirname
的效果相同,不会因为启动脚本的目录不一样而改变,在其他情况下跟process.cwd()
效果相同,是相对于启动脚本所在目录的路径。总结:
只有在
require()
时才使用相对路径(./, ../)
的写法,其他地方一律使用绝对路径,如下:最后看看改过之后的结果,不会报错找不到文件了,不管在哪里执行这个脚本文件,都不会出错了,防止以后踩坑。
The text was updated successfully, but these errors were encountered: