在 Vercel 无服务器函数上部署由 WebAssembly 支持的 Next.js 应用

2025-06-07

在 Vercel 无服务器函数上部署由 WebAssembly 支持的 Next.js 应用

您将在本文中发现什么?

JavaScript 很棒,但有时你需要运行一些 JavaScript 中无法直接使用的代码。在本文中,我们将了解如何使用 Next.js 和 Vercel 在无服务器 Node.js 函数中运行 WebAssembly。

谢谢JS

Papermark - 开源的 DocSend 替代品。

在开始之前,我先来介绍一下 Papermark。它是 DocSend 的开源替代方案,可帮助您管理安全的文档共享,包括实时分析、自定义域名等等。它完全开源!

如果你能给我们一颗星,我会非常高兴!别忘了在评论区分享你的想法❤️
https://github.com/mfts/papermark

Papermark 应用程序

设置项目

让我们继续为页码计数应用程序设置项目环境。我们将创建一个 Next.js 应用,并设置为在无服务器函数中运行 WebAssembly 包。

使用 TypeScript 和 Tailwindcss 设置 Next.js

我们将使用它create-next-app来生成一个新的 Next.js 项目。我们还将使用 TypeScript 和 Tailwind CSS,因此请确保在出现提示时选择这些选项。

npx create-next-app

# ---
# you'll be asked the following prompts
What is your project named?  my-app
Would you like to add TypeScript with this project?  Y/N
# select `Y` for typescript
Would you like to use ESLint with this project?  Y/N
# select `Y` for ESLint
Would you like to use Tailwind CSS with this project? Y/N
# select `Y` for Tailwind CSS
Would you like to use the `src/ directory` with this project? Y/N
# select `N` for `src/` directory
What import alias would you like configured? `@/*`
# enter `@/*` for import alias
Enter fullscreen mode Exit fullscreen mode

安装 vercel/blob

Vercel Storage 发布了一个名为 的新软件包@vercel/blob,可让您将文件上传到 Vercel 的文件存储。我们将使用此软件包来存储我们的 PDF 文件。

npm install @vercel/blob
Enter fullscreen mode Exit fullscreen mode

安装 mupdf

MuPDF 是一款轻量级的 PDF、XPS 和电子书查看器,但它自带一个wasm包,可以让你操作和注释 PDF。我们将使用这个包来统计 PDF 的页数。

npm install mupdf
Enter fullscreen mode Exit fullscreen mode

构建应用程序

现在我们已经完成了设置,可以开始构建应用程序了。我们将介绍的主要功能包括:

  • 上传文件
  • 使用 WASM 包统计页面总数
  • 使 WASM 在 Vercel 的无服务器功能上运行

#1 上传文件

让我们创建一个无服务器函数,将文件上传到 Vercel 的文件存储。发送一个POST请求,并在请求正文中将 object作为/api/upload一个file键。FormData

// pages/api/upload.ts
import { put } from "@vercel/blob";
import { NextResponse, NextRequest } from "next/server";

export const config = {
  runtime: "edge",
};

export default async function upload(request: NextRequest) {
  const form = await request.formData();
  const file = form.get("file") as File;

  if (!file) {
    return NextResponse.json(
      { error: "File name or file not submitted" },
      { status: 400 }
    );
  }

  const blob = await put(file.name, file, { access: "public" });

  return NextResponse.json(blob);
}
Enter fullscreen mode Exit fullscreen mode

blob包含有关我们的文件的数据,包括url我们稍后将用来访问该文件的数据。

警告:此无服务器实现仅适用于小于 4MB 的文件。如果您需要上传更大的文件,则需要使用客户端上传更多信息请参阅 GitHub)。

#2 使用 WASM 包计算页面总数

现在我们已经上传了文件,我们可以使用该mupdf包来计算 PDF 的总页数。我们将创建一个无服务器函数,该函数接收文件的urlfromblob对象并返回总页数。

在他们的网站mupdf上查找该软件包的完整文档

// pages/api/count-pages.ts
import { NextApiRequest, NextApiResponse } from "next";
// @ts-ignore
import mupdf from "mupdf";

export default async (req: NextApiRequest, res: NextApiResponse) => {
  // check if it's a POST method
  if (req.method !== "POST") {
    res.status(405).json({ error: "Method Not Allowed" });
    return;
  }

  try {
    const { url } = req.body as { url: string };
    // Fetch the PDF data
    const response = await fetch(url);
    // Convert the response to an ArrayBuffer
    const pdfData = await response.arrayBuffer();
    // Create a MuPDF instance
    var doc = mupdf.Document.openDocument(pdfData, "application/pdf");
    // Get the number of pages
    var n = doc.countPages();

    // Send the images as a response
    res.status(200).json({ numPages: n });
  } catch (error) {
    console.error("Error:", error);
    res.status(500).json({ error: "Internal Server Error" });
  }
};
Enter fullscreen mode Exit fullscreen mode

此函数在本地运行良好,但部署到 Vercel 时会失败。这是因为node_modules 包wasm中的文件mupdf未包含在部署包中。我们将在下一步中修复此问题。

#3 让 WASM 在 Vercel 的无服务器功能上运行

为了使该wasm文件可用于 Vercel 的无服务器功能,我们需要wasm在部署中包含包的 node_modules 文件夹中的文件。我们可以通过在next.config.js文件中添加以下内容来实现这一点。

在这种情况下,我们使用experimental.outputFileTracingIncludes选项将包wasm中的文件包含mupdf到我们的部署到 API 路由中/api/count-pages

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    outputFileTracingIncludes: {
      "/api/count-pages": ["./node_modules/mupdf/lib/*.wasm"],
    },
  },
};

module.exports = nextConfig;
Enter fullscreen mode Exit fullscreen mode

就是这样。现在我们可以将应用程序部署到 Vercel,它将按预期工作。

结论

就这样!我们使用 Next.js、WebAssembly 和 Vercel 无服务器函数构建了一个简单的应用程序,用于统计 PDF 文档的页数。虽然这里的示例很简单,但相同的概念可以应用于处理任何其他可以扩展应用功能的 WebAssembly 软件包。

感谢您的阅读。我是 Marc,一位开源倡导者。我正在构建papermark.com ——DocSend 的开源替代方案。

继续尝试,突破这些技术所能带来的无限可能。祝您编程愉快!

帮帮我!

如果您觉得这篇文章对您有帮助,并且对 Vercel 无服务器函数上的 WebAssembly 有了更好的理解,请给我们一颗星,我将不胜感激!别忘了在评论区分享您的想法哦 ❤️

https://github.com/mfts/papermark

猫谢谢

文章来源:https://dev.to/mfts/deploy-a-web assembly-powered-nextjs-app-on-vercel-serverless-functions-20b0
PREV
如何为你的 GitHub 项目编写完美的 README
NEXT
使用 Next.js 和 OpenAI 构建 AI 助手来与您的文档进行聊天