You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过NPM包在Next.js中动态加载JSON遇路径错误问题

动态加载JSON配置文件路径错误问题解决

问题场景

本地TypeScript项目中,通过PlatformConfigurationFactory.getInstance动态加载src/data下的JSON配置文件一切正常,但将项目发布为NPM包并在Next.js 14项目中安装调用时,出现文件路径错误:

Error loading configuration for facebook: [Error: ENOENT: no such file or directory, open '/Users/me/workspace/nextjs/.next/server/json/facebook-config.json'] {
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '/Users/me/workspace/nextjs/.next/server/json/facebook-config.json'
}
⨯ Error: Configuration data not found

代码试图在Next.js的构建目录中查找配置文件,而非NPM包内部的dist/data路径。

问题原因

__dirname的指向在Next.js服务器端打包环境中发生了变化:Next.js会将依赖包的代码打包到自身的构建目录中,导致原本基于__dirname计算的相对路径不再指向NPM包内部的配置文件位置。

解决方案

方案一:静态导入配置文件(推荐)

将JSON配置文件作为模块静态导入,避免运行时动态读取文件,配置内容会直接嵌入到编译后的代码中,彻底规避路径问题。

修改JsonConfigurationRepository:

import { IConfigurationRepository } from "../../application/interfaces/IJsonConfigurationRepository";
import { Platform } from "../../core/domain/Platform";
// 静态导入所有平台配置文件
import facebookConfig from "../../data/facebook-config.json";
import twitterConfig from "../../data/twitter-config.json";

export class JsonConfigurationRepository implements IConfigurationRepository {
  async getConfig(platform: Platform): Promise<any> {
    // 建立平台与配置的映射
    const configMap = {
      [Platform.Facebook]: facebookConfig,
      [Platform.Twitter]: twitterConfig,
      // 扩展其他平台配置
    };

    return configMap[platform] || null;
  }
}

方案二:修正路径计算逻辑并确保配置文件被正确发布

  1. 确保配置文件被包含在NPM包中:在项目的package.json中添加files字段,明确指定要发布的文件:
{
  "files": [
    "dist",
    "src/data/*.json"
  ]
}
  1. 使用require.resolve获取正确路径:替换基于__dirname的路径计算,改用require.resolve自动解析配置文件的绝对路径:
import { IConfigurationRepository } from "../../application/interfaces/IJsonConfigurationRepository";
import { Platform } from "../../core/domain/Platform";
import fs from "fs/promises";

export class JsonConfigurationRepository implements IConfigurationRepository {
  async getConfig(platform: Platform): Promise<any> {
    const fileName = `${platform}-config.json`;
    try {
      // 自动解析配置文件的绝对路径
      const filePath = require.resolve(`../data/${fileName}`);
      const fileContent = await fs.readFile(filePath, "utf-8");
      return JSON.parse(fileContent);
    } catch (error) {
      console.error(`Error loading configuration for ${platform}:`, error);
      return null;
    }
  }
}

如果项目使用ES模块(tsconfig中module为ESNext),可以改用import.meta.url计算路径:

import { IConfigurationRepository } from "../../application/interfaces/IJsonConfigurationRepository";
import { Platform } from "../../core/domain/Platform";
import fs from "fs/promises";
import { fileURLToPath } from 'url';
import { dirname, resolve } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

export class JsonConfigurationRepository implements IConfigurationRepository {
  async getConfig(platform: Platform): Promise<any> {
    const fileName = `${platform}-config.json`;
    const filePath = resolve(__dirname, "../../data", fileName);

    try {
      const fileContent = await fs.readFile(filePath, "utf-8");
      return JSON.parse(fileContent);
    } catch (error) {
      console.error(`Error loading configuration for ${platform}:`, error);
      return null;
    }
  }
}

方案三:构建时复制配置文件到dist目录

修改项目的构建脚本,在TypeScript编译完成后,将src/data目录复制到dist目录中:

{
  "scripts": {
    "build": "tsc && cp -r src/data dist/"
  }
}

确保编译后dist/data目录存在,此时基于__dirname的路径计算就能正确指向NPM包内部的配置文件。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:05:16