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

Vercel部署环境下如何在API路由中正确读取文件

解决Vercel部署后Nuxt API无法读取本地文件夹的问题

问题原因

Vercel的无服务器函数环境中,process.cwd()指向的是函数执行的临时工作目录,而非项目根目录;同时未明确标记的本地文件夹不会被打包进函数部署包,导致fs.readdirSync找不到目标目录。

正确实现步骤

1. 配置Nitro将素材目录标记为服务器资产

在nuxt.config.ts中添加Nitro配置,将characters目录设为非公开的服务器资产,确保部署时该目录会被打包到函数环境中:

export default defineNuxtConfig({
  nitro: {
    publicAssets: [
      {
        dir: './characters',
        serve: false, // 禁止公开访问该目录,符合隐私需求
        maxAge: 31536000 // 高频访问场景建议设置较长缓存时长
      }
    ]
  }
})

2. 修改API路由使用Nitro存储读取目录

利用Nitro的useStorage可以读取整个目录的文件列表,替代原生fs模块。修改server/api/read-characters.ts代码如下:

export default defineEventHandler(async (event) => {
  // 获取characters目录下的所有文件路径(带前缀)
  const fileKeys = await useStorage('assets:').getKeys('characters/')
  // 提取纯文件名,去掉"characters/"前缀
  const files = fileKeys.map(key => key.split('/').pop())
  return files
})

如果需要读取单个文件内容(用于图片叠加计算),可以直接通过存储路径获取:

// 示例:读取指定素材文件的Buffer
const getCharacterAsset = async (filename) => {
  return await useStorage('assets:characters/').getItem(filename)
}

3. 针对高频访问与大文件的优化

  • 缓存文件列表:将文件列表缓存到内存,避免每次请求都遍历目录。可以用Nitro内置缓存:
    const cachedFiles = await useCache().get('characters:filelist')
    if (!cachedFiles) {
      const fileKeys = await useStorage('assets:').getKeys('characters/')
      const files = fileKeys.map(key => key.split('/').pop())
      await useCache().set('characters:filelist', files, { ttl: 3600 }) // 缓存1小时
      return files
    }
    return cachedFiles
    
  • 按需加载文件:仅在需要处理某张素材时才读取对应文件,避免一次性加载全部50MB+的文件,节省内存与带宽。
  • 使用Edge Functions:如果访问频率极高,可将API路由改为Edge Function(在文件名后加.edge.ts),进一步降低响应延迟。

注意事项

  • 确保characters目录未被.gitignore排除,否则部署时Vercel不会上传该目录。
  • 若素材文件更新,需重新部署项目以同步最新文件到服务器资产中。
  • 二进制文件(如图片)通过useStorage读取时会直接返回Buffer,可直接用于后续图片处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:01:26