首页 > 解决方案 > 在 Vercel 上部署 NextJS 的 API 路由上使用 fileSystem

问题描述

我需要在 NextJS 的 API 路由上使用 fileStystem 方法作为 readdirSync。它在本地工作,但当部署在 Vercel 上时,请求会以 500 状态代码响应。

这是 Vercel 的功能日志:

catch Error: ENOENT: no such file or directory, scandir '/var/task/_posts'
    at Object.readdirSync (fs.js:1043:3)
    at getAllArticles (/var/task/.next/server/chunks/230.js:135:67)
    at __WEBPACK_DEFAULT_EXPORT__ (/var/task/.next/server/pages/api/search.js:37:93)
    at Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils.js:101:15)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async Server.handleApiRequest (/var/task/node_modules/next/dist/server/next-server.js:770:9)
    at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:661:37)
    at async Router.execute (/var/task/node_modules/next/dist/server/router.js:205:32)
    at async Server.run (/var/task/node_modules/next/dist/server/next-server.js:841:29)
    at async Server.handleRequest (/var/task/node_modules/next/dist/server/next-server.js:292:20) {
  errno: -2,
  syscall: 'scandir',
  code: 'ENOENT',
  path: '/var/task/_posts'
}

这是 API 路由本身 (/pages/api/search.ts):

export default (req: NextApiRequest, res: NextApiResponse) => {
  const { query } = req;

  try {
    if (query.q) {
      const posts = getAllArticles(ArticleTypes.POSTS, ['slug', 'href', 'title', 'category'], {
        hints: {
          hint: query.q as string,
          fields: ['title', 'category'],
        },
      }).map((post) => post.data);

      const projects = getAllArticles(ArticleTypes.PROJECTS, ['slug', 'href', 'title', 'category', 'technologies'], {
        hints: {
          hint: query.q as string,
          fields: ['title', 'category', 'technologies'],
        },
      }).map((project) => project.data);

      res.status(200).json({
        ...(posts.length > 0) && { posts },
        ...(projects.length > 0) && { projects },
      });
    } else {
      res.status(422).send('El parámetro "q" es necesario.');
    }
  } catch (e) {
    res.status(500).send('Ha ocurrido un error mientras se intentaba hacer la búsqueda.');
  }
};

这是其中getAllArticles()使用的功能:

export const getAllArticles = (
  type: ArticleTypes,
  items?: string[],
  filters?: IFilters,
): IArticle[] => {
  const articlesPath = join(process.cwd(), `_${type}`);

  const articlesNames = fs
    .readdirSync(articlesPath)
    .filter((path) => /\.mdx$/.test(path));

  const mergedItems: string[] = Array.from(new Set([
    ...(items && items.length > 0) ? items : [],
    ...(filters?.hints && filters.hints.fields.length > 0) ? filters.hints.fields : [],
  ]));

  const allArticles = articlesNames
    .map((article) => getArticle(type,
      path.parse(article).name,
      mergedItems.length > 0
        ? mergedItems
        : undefined));

  const filteredArticles = filterArticles(type, allArticles, filters);

  return filteredArticles;
};

所以我目前正在使用fs.readdirSync读取 .mdx 文件。正如我之前提到的,这在本地运行得非常好,但在 Vercel 上部署时就不行了。我需要配置任何类型的配置文件或任何东西吗?

太感谢了!

标签: node.jsapinext.jsfsvercel

解决方案


推荐阅读