为什么在使用Next.js SSR时无法读取Vercel上的JSON文件?

vltsax25  于 2023-04-05  发布在  其他
关注(0)|答案(3)|浏览(236)

我有一个由三个主文件组成的准系统Next.js项目(如下所示),我试图用JSON文件中的数据生成索引页面。如果我使用getStaticProps将项目部署到Vercel,一切都正常。
然而,当我使用getServerSideProps进行部署时,项目构建时,我得到的是“500:访问网站时出现“内部服务器错误”,Vercel的Functions日志中出现错误消息(也在下面列出)。我可以在本地使用getServerSideProps在开发和部署模式下运行应用程序,只是不在Vercel上。
为什么在使用getStaticProps而不是getServerSideProps部署到Vercel时,项目能够找到JSON文件?
pages/index.tsx:

import { GetStaticProps, GetServerSideProps } from 'next';
import { User, getUsers } from '../lib/users';

// export const getStaticProps: GetStaticProps = async () => {
export const getServerSideProps: GetServerSideProps = async () => {
    const users = await getUsers();
    return { props: { users } };
};

export default function Home({ users }) {
    return (
        <div>
            {users.map((user: User) => (
                <p key={user.id}>{user.name}</p>
            ))}
        </div>
    );
}

lib/users.ts:

import fs from 'fs';

export interface User {
    id: number;
    name: string;
}

export function getUsers(): User[] {
    const users = JSON.parse(fs.readFileSync('data/users.json').toString());
    return users;
}

data/users.json:

[
    { "id": 1, "name": "Alice" },
    { "id": 2, "name": "Bob" },
    { "id": 3, "name": "Charlie" }
]

Vercel的函数日志:

[GET] /
09:41:25:73
2022-03-11T17:41:26.362Z    c8febc98-491a-4433-a2af-6dd7be25b040    ERROR   Error: ENOENT: no such file or directory, open 'data/users.json'
    at Object.openSync (fs.js:497:3)
    at Object.readFileSync (fs.js:393:35)
    at getUsers (/var/task/.next/server/pages/index.js:28:52)
    at getServerSideProps (/var/task/.next/server/pages/index.js:40:25)
    at Object.renderToHTML (/var/task/node_modules/next/dist/server/render.js:566:26)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async doRender (/var/task/node_modules/next/dist/server/base-server.js:855:38)
    at async /var/task/node_modules/next/dist/server/base-server.js:950:28
    at async /var/task/node_modules/next/dist/server/response-cache.js:63:36 {
  errno: -2,
  syscall: 'open',
  path: 'data/users.json',
  page: '/'
}
RequestId: c8febc98-491a-4433-a2af-6dd7be25b040 Error: Runtime exited with error: exit status 1
Runtime.ExitError
a1o7rhls

a1o7rhls1#

确保数据文件夹放置在公用文件夹中。

public
 data
   user.json
pages
styles

并在fs.readFileSync中加上一个斜杠

export function getUsers(): User[] {
const users = JSON.parse(fs.readFileSync('/data/users.json').toString());
return users;
}

JSON应该是这样的:

{
"users" : [
  { "id": 1, "name": "Alice" },
  { "id": 2, "name": "Bob" },
 { "id": 3, "name": "Charlie" }
]
}
q0qdq0h2

q0qdq0h22#

这是在服务器端阅读JSON数据的另一种方式,如getServerSideProps函数。
1.在项目的根目录下创建一个名为data的文件夹,并将JSON文件放在该目录中。
1.然后在有getServerSideProps的页面上,您可以像这样导入文件。

export async function getServerSideProps(){
  // path to the JSON file
  const staticData = await import('../../../data/index.json').then((res) => res.default);
  console.log("Json data" , staticData);
  return {
     props : {
        data : staticData || null
      }
   }
}

然后检查控制台,您应该看到作为对象的响应。

你也可以像前面的答案那样使用单独的函数,只要确保文件在root目录下,而不是在public目录下,然后将函数更改为async函数。

export async function getUsers(): User[] {
 const users = await import('../data/index.json').then((res) => res.default);
   return users;
}

在getServerSideProps中,只需导入函数并从那里调用它。

eyh26e7m

eyh26e7m3#

我希望这有助于使用process.cwd()读取文件

import fse from "fs-extra"
import path from "path"

 const filePath = path.join(process.cwd(), "firebaseServiceAccount.json")

     fse.readFile(filePath, 'utf-8', async (error, data) => {
     
      const jsonData = JSON.parse(data);

     })

相关问题