在 API 路由上使用文件系统,NextJS 部署在 Vercel 上

问题描述 投票:0回答:1

我需要在 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.js api next.js fs vercel
1个回答
0
投票

您必须告诉 Next.js 将您的 MDX 文件包含在无服务器函数的文件系统中

module.exports = {
  experimental: {
    outputFileTracingIncludes: {
      '/api/search': ['./_posts/*.mdx'],
    },
  },
}

https://vercel.com/guides/how-can-i-use-files-in-serverless-functions

© www.soinside.com 2019 - 2024. All rights reserved.