NextJS/Vercel 在生产环境中未能提供位于 public 文件夹中的 .pdf 文件。

huangapple go评论59阅读模式
英文:

NextJS/Vercel not serving .pdf file in public folder in production

问题

I have a PDF file in my public folder (next js app), which I'm attaching to an email (sendgrid).

在我的公共文件夹中有一个PDF文件(Next.js应用程序),我将其附加到一封电子邮件中(SendGrid)。

In development, everything is working fine. Also when I run build + run start. So I suppose this has something to do with Vercel. When I check the logs in production (Vercel), I see following error:

在开发中,一切都正常工作。当我运行构建 + 运行启动时也是如此。因此,我认为这与Vercel有关。当我在生产环境(Vercel)中检查日志时,我看到以下错误:

Error: ENOENT: no such file or directory, open 'public/assets/Bonus_1.pdf'

错误:ENOENT:没有此文件或目录,打开 'public/assets/Bonus_1.pdf'

Any ideas on how to solve this problem?

有关如何解决此问题的任何想法吗?

Here's the relevant code:

以下是相关的代码:

const pathToAttachment1 = path.join("public", "assets", "Bonus_1.pdf")
const attachment1 = fs.readFileSync(pathToAttachment1).toString("base64");

sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
     to: process.env.NODE_ENV === "development" ? "info@test.com" : email,
     from: "test",
     attachments: [
            {
              content: attachment1,
              filename: "Bonus_1.pdf",
              type: "application/pdf",
              disposition: "attachment",
            },
          ],
          templateId: "xxx",
        };
sgMail.send(msg).then(() => {res.status(200).json({ message: "Mail sent!" });
});

To check the assets in the public directory I've added following code:

为了检查公共目录中的资源,我添加了以下代码:

const files = fs.readdirSync(path.join("public", "assets"))
console.log("files:", files)

The output looks as follows:

输出如下:

files: [
  '1.png',
  'Bonus_1.pdf' ]
英文:

I have a PDF file in my public folder (next js app), which I'm attaching to an email (sendgrid).

In development, everything is working fine. Also when I run build + run start. So I suppose this has something to do with Vercel. When I check the logs in production (Vercel), I see following error:

> Error: ENOENT: no such file or directory, open 'public/assets/Bonus_1.pdf'

Any ideas on how to solve this problem?

Here's the relevant code:

const pathToAttachment1 = path.join("public", "assets", "Bonus_1.pdf")
const attachment1 = fs.readFileSync(pathToAttachment1).toString("base64");
    
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
     to: process.env.NODE_ENV === "development" ? "info@test.com" : email,
     from: "test",
     attachments: [
            {
              content: attachment1,
              filename: "Bonus_1.pdf",
              type: "application/pdf",
              disposition: "attachment",
            },
          ],
          templateId: "xxx",
        };
sgMail.send(msg).then(() => {res.status(200).json({ message: "Mail sen!" });
});

To check the assets in the public directory I've added following code:

const files = fs.readdirSync(path.join("public", "assets"))
console.log("files:", files)

The output looks as follows:

files: [
  '1.png',
  'Bonus_1.pdf' ]

答案1

得分: 0

如果文件位于公共目录中,您提供的路径是错误的。不需要将公共文件夹包含在资源路径中。

考虑到这一点,您的路径应该是:/assets/Bonus_1.pdf

记住

Vercel的部署文件系统是只读的,因此在部署到云时,任何导致文件被打开或修改的操作(例如使用fs模块的某些方法)都会导致错误。

英文:

If the file is contained in the public directory, the path you have provided is wrong. The public folder does not to be included in the resource path.

Taking that into account your path should be: /assets/Bonus_1.pdf.

Remember

Vercel's deployment file system is read only, so any actions that will cause the file to be opened or modified like when using certain methods of the fs module, will error when deployed to the cloud.

答案2

得分: 0

我最初假设你正在app目录下运行代码(在我的测试中,你的代码在那里运行得非常好),但最终我成功在pages/api下复制了你的问题。

path.resolve 应该能解决你的错误:

const file = fs
  .readFileSync(path.resolve("public/assets/Bonus_1.pdf"))
  .toString("base64");
英文:

I initially assumed that you are running your code under the app dir (and your code worked perfectly fine there in my tests), but I was finally able to replicate your issue under the pages/api.

path.resolve should resolve your error:

const file = fs
  .readFileSync(path.resolve("public/assets/Bonus_1.pdf"))
  .toString("base64");

huangapple
  • 本文由 发表于 2023年5月17日 23:46:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76273933.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定