发布npm包后fs.readdirSync路径错误 如何读取包自身目录文件
问题根因
Node.js的fs模块传入相对路径时,解析基准是进程启动时的工作目录,也就是process.cwd()的返回值,根本不会参考当前执行的js文件存放位置。
本地开发时启动脚本的终端工作目录刚好是npm包自身的根目录,所以"./"指向包目录,读取结果符合预期;等包被安装到其他项目中,用户在自己项目根目录运行代码时,进程工作目录会变成新项目的根目录,"./"自然就指向新项目目录了。
正确实现
要固定读取npm包自身目录下的文件,必须传入基于当前代码文件位置的绝对路径,根据使用的模块规范选对应写法即可:
CommonJS 模块
Node.js内置的__dirname变量直接返回当前js文件所在目录的绝对路径,直接传给readdirSync就行:
const fs = require('fs'); // 读取当前文件所在目录的文件列表 const dirents = fs.readdirSync(__dirname, { withFileTypes: true }); console.log(dirents);
如果入口文件在包的子目录(比如src/index.js),要读取包根目录的话,用path模块拼接路径跳对应层级即可:
const path = require('path'); // 从src目录往上跳一级就是包根目录 const packageRoot = path.resolve(__dirname, '../'); const rootDirents = fs.readdirSync(packageRoot, { withFileTypes: true });
ES Module 模块
ESM环境没有内置__dirname,需要先通过import.meta.url自行构造:
import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // 后续用法和CommonJS完全一致 const dirents = fs.readdirSync(__dirname, { withFileTypes: true });
避坑提醒
- 不要硬编码npm包的安装路径,npm、pnpm、yarn不同版本、不同依赖安装模式下,包的实际存放位置差异很大,基于
__dirname动态取路径是唯一通用的方案 - 路径拼接一律使用
path模块的API,不要手动拼接斜杠,避免Windows和类Unix系统的路径分隔符不兼容问题
内容的提问来源于stack exchange,提问作者Feizhang210291
相关产品推荐
相关产品推荐

