在 Vercel 无服务器函数上部署由 WebAssembly 支持的 Next.js 应用
您将在本文中发现什么?
JavaScript 很棒,但有时你需要运行一些 JavaScript 中无法直接使用的代码。在本文中,我们将了解如何使用 Next.js 和 Vercel 在无服务器 Node.js 函数中运行 WebAssembly。
Papermark - 开源的 DocSend 替代品。
在开始之前,我先来介绍一下 Papermark。它是 DocSend 的开源替代方案,可帮助您管理安全的文档共享,包括实时分析、自定义域名等等。它完全开源!
如果你能给我们一颗星,我会非常高兴!别忘了在评论区分享你的想法❤️
https://github.com/mfts/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
安装 vercel/blob
Vercel Storage 发布了一个名为 的新软件包@vercel/blob
,可让您将文件上传到 Vercel 的文件存储。我们将使用此软件包来存储我们的 PDF 文件。
npm install @vercel/blob
安装 mupdf
MuPDF 是一款轻量级的 PDF、XPS 和电子书查看器,但它自带一个wasm包,可以让你操作和注释 PDF。我们将使用这个包来统计 PDF 的页数。
npm install mupdf
构建应用程序
现在我们已经完成了设置,可以开始构建应用程序了。我们将介绍的主要功能包括:
- 上传文件
- 使用 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);
}
blob
包含有关我们的文件的数据,包括url
我们稍后将用来访问该文件的数据。
警告:此无服务器实现仅适用于小于 4MB 的文件。如果您需要上传更大的文件,则需要使用客户端上传(更多信息请参阅 GitHub)。
#2 使用 WASM 包计算页面总数
现在我们已经上传了文件,我们可以使用该mupdf
包来计算 PDF 的总页数。我们将创建一个无服务器函数,该函数接收文件的url
fromblob
对象并返回总页数。
在他们的网站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" });
}
};
此函数在本地运行良好,但部署到 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;
就是这样。现在我们可以将应用程序部署到 Vercel,它将按预期工作。
结论
就这样!我们使用 Next.js、WebAssembly 和 Vercel 无服务器函数构建了一个简单的应用程序,用于统计 PDF 文档的页数。虽然这里的示例很简单,但相同的概念可以应用于处理任何其他可以扩展应用功能的 WebAssembly 软件包。
感谢您的阅读。我是 Marc,一位开源倡导者。我正在构建papermark.com ——DocSend 的开源替代方案。
继续尝试,突破这些技术所能带来的无限可能。祝您编程愉快!
帮帮我!
如果您觉得这篇文章对您有帮助,并且对 Vercel 无服务器函数上的 WebAssembly 有了更好的理解,请给我们一颗星,我将不胜感激!别忘了在评论区分享您的想法哦 ❤️
https://github.com/mfts/papermark
