Node.js fs.existsSync返回误报:不存在的目录被判定为存在
解决Node.js fs.existsSync误报目录存在的问题
问题场景
我编写了如下Node.js代码,逻辑为:检查.fs目录是否存在,若不存在则创建该目录;再检查.fs/token.txt文件是否存在,若不存在则生成哈希密码并写入该文件,之后使用该令牌进行身份验证。
const fs = await import("fs"); let hashedPassword; if (!fs.existsSync(".fs")) { fs.mkdirSync(".fs"); console.info("No cache found. Creating .fs"); } if (!fs.existsSync(".fs/token.txt")) { console.info("No token found, hashing a new one"); hashedPassword = bcypt.hashSync( password || (process.env.UNIVERSAL_FS_PASSWORD as string), 10 ); fs.writeFileSync(".fs/token.txt", hashedPassword); } // TODO: add correct url const response = await fetch("http://localhost:3000/", { headers: { Authorization: `Bearer ${hashedPassword}` } }); if (response.status === 401) { console.error("Failed to authenticate. Check your password"); } else if (response.status === 200) { console.info("Authenticated"); } else if (response.status === 500) { console.info("Something else went wrong. Check your server logs"); }
但实际情况是,.fs目录在系统中并不存在,执行ls命令查看当前目录也未显示该目录:
README.md eslint.config.js package.json rollup.config.mjs tests types dist node_modules pnpm-lock.yaml src tsconfig.json vite.config.ts
然而调用fs.existsSync(".fs")却返回true,打印fs.stat的结果如下:
Stats { dev: 16777232, mode: 33188, nlink: 1, uid: 501, gid: 20, rdev: 0, blksize: 4096, ino: 52057046, size: 60, blocks: 8, atimeMs: 1719445593768.046, mtimeMs: 1719445593768.1392, ctimeMs: 1719445593768.1392, birthtimeMs: 1719445593768.046 }
我的环境信息:
System: OS: macOS 14.5 CPU: (12) arm64 Apple M2 Max Memory: 8.82 GB / 32.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 22.3.0 - /opt/homebrew/bin/node npm: 10.8.1 - /opt/homebrew/bin/npm pnpm: 9.4.0 - ~/Library/pnpm/pnpm bun: 1.1.17 - ~/.bun/bin/bun Managers: Homebrew: 4.3.7 - /opt/homebrew/bin/brew pip3: 24.0 - /opt/homebrew/bin/pip3 RubyGems: 3.0.3.1 - /usr/bin/gem Utilities: Make: 3.81 - /usr/bin/make GCC: 15.0.0 - /usr/bin/gcc Git: 2.39.3 - /usr/bin/git Clang: 15.0.0 - /usr/bin/clang FFmpeg: 7.0.1 - /opt/homebrew/bin/ffmpeg Curl: 8.6.0 - /usr/bin/curl OpenSSL: 3.3.1 - /opt/homebrew/bin/openssl Servers: Apache: 2.4.58 - /usr/sbin/apachectl Virtualization: Docker: 26.1.4 - /usr/local/bin/docker Docker Compose: 2.27.1 - /usr/local/bin/docker-compose Parallels: 19.3.0 - /usr/local/bin/prlctl SDKs: iOS SDK: Platforms: DriverKit 23.5, iOS 17.5, macOS 14.5, tvOS 17.5, visionOS 1.2, watchOS 10.5 IDEs: VSCode: 1.90.2 - /usr/local/bin/code Vim: 9.0 - /usr/bin/vim Xcode: 15.4/15F31d - /usr/bin/xcodebuild Languages: Bash: 3.2.57 - /bin/bash Java: 21.0.2 - /usr/bin/javac Perl: 5.34.1 - /usr/bin/perl Python3: 3.12.3 - /opt/homebrew/bin/python3 Ruby: 2.6.10 - /usr/bin/ruby Databases: SQLite: 3.43.2 - /usr/bin/sqlite3 Browsers: Safari: 17.5
解决方案
- 确认进程工作目录:Node.js的fs模块基于进程当前工作目录(CWD)判断路径,不一定是你执行
ls的目录。在代码开头添加console.log(process.cwd()),查看实际的工作目录,确认.fs是否存在于该路径下。 - 显示隐藏文件:macOS中以
.开头的文件/目录默认隐藏,执行ls -a命令重新查看当前目录,确认.fs是否实际存在。 - 检查文件类型:从你打印的Stats信息来看,
mode: 33188对应普通文件(目录的mode通常为16877)。也就是说,系统中存在一个名为.fs的文件而非目录,导致fs.existsSync返回true,但mkdirSync会因为同名文件存在而失败(你代码中未捕获这个错误)。解决方法是删除这个同名文件,再重新运行代码。 - 清理文件系统缓存:macOS的文件系统可能存在缓存,尝试重启Node进程,或者用Finder的
Cmd+Shift+G输入.fs直接定位。必要时可执行diskutil resetUserPermissions / $(id -u)重置权限缓存(操作前备份重要数据)。 - 改用更可靠的API:
fs.existsSync已被官方不推荐,建议使用fs.statSync结合类型判断,避免误判:
try { const stats = fs.statSync(".fs"); if (!stats.isDirectory()) { // 不是目录,先删除再创建 fs.unlinkSync(".fs"); fs.mkdirSync(".fs"); console.info("Found non-directory .fs, replaced with directory"); } } catch (err) { if (err.code === 'ENOENT') { // 不存在,创建目录 fs.mkdirSync(".fs"); console.info("No cache found. Creating .fs"); } else { // 其他错误抛出 throw err; } }
内容的提问来源于stack exchange,提问作者Ethan
相关产品推荐
相关产品推荐

