You need to enable JavaScript to run this app. Node.js模块发布前测试 存在data目录却报ENOENT scandir './data'错误的修复方法
优惠活动
大模型
产品
解决方案
定价
更多

Node.js模块发布前测试 存在data目录却报ENOENT scandir './data'错误的修复方法

报错核心根源

错误本质是代码中使用的./data是相对于进程运行工作目录(cwd)的相对路径,并非相对于代码文件本身的位置。

  • 当你在模块根目录test-main下运行测试时,进程的cwd就是模块根目录,./data可以正常匹配到实际存在的文件夹,功能完全正常。
  • 当你在外层测试目录通过本地路径安装模块、再运行代码时,进程的cwd切换到了外层测试目录,系统会尝试在这个外层目录下查找./data,自然会抛出文件不存在的错误。
当前临时修复方案的缺陷

你替换的./node_modules/random-usernames/data路径只是凑巧能在当前测试环境生效,并非可长期使用的兼容实现:

  • 这本质还是基于cwd的相对路径,只要运行脚本时的工作目录不是安装你模块的项目根目录(比如用户在自己项目的src子目录下执行脚本),路径就会直接失效。
  • 现代包管理器(pnpm、Yarn PnP)不会把依赖文件平铺在项目根的node_modules路径下,目录结构和传统npm存在差异,硬编码的这个路径在这类环境下100%无法正常访问。
  • 当用户对项目做了依赖提升、外置node_modules等定制配置时,这个路径也会立刻触发文件找不到的错误。
标准修复流程

1. 锚定模块自身的资源路径

彻底抛弃依赖cwd的相对路径,基于代码文件本身的位置拼接资源路径,不受运行时目录切换的影响:

  • CommonJS语法的模块,直接使用内置全局变量__dirname,它的值永远是当前代码文件所在目录的绝对路径。
  • 搭配内置path模块拼接路径,自动适配Windows、macOS、Linux的路径分隔符,避免跨平台兼容问题。
    替换原代码的示例:
const fs = require('fs');
const path = require('path');
// 定位模块自身根目录下的data文件夹
const dataDir = path.join(__dirname, 'data');
fs.readdirSync(dataDir);
  • 如果是ES Module语法的模块,没有内置__dirname变量,可以通过import.meta.url获取当前文件的绝对路径完成拼接:
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const dataDir = path.join(__dirname, 'data');
fs.readdirSync(dataDir);

2. 保证发布包包含data目录

路径逻辑修改完成后,需要确认npm发布时会将data目录打包进正式的包文件,避免线上环境出现资源缺失:

  • 在模块根目录的package.json中,通过files字段明确声明需要打包上传的内容,将data/**/*加入数组,示例配置:
    {
      "files": [
        "lib/**/*",
        "data/**/*"
      ]
    }
    
  • 不建议完全依赖.npmignore做反向排除,避免误将data目录过滤掉导致发布的包缺失资源。

内容的提问来源于stack exchange,提问作者divinelemon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 10:45:00