-
Notifications
You must be signed in to change notification settings - Fork 840
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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: