解决 Node.js 中 pdf.js DOMMatrix is not defined 错误
问题背景
在使用 Node.js 环境下运行 pdf.js 时,经常会遇到 DOMMatrix is not defined 的错误。这是因为 DOMMatrix 是浏览器环境中的 Web API,在 Node.js 环境中默认是不存在的。
错误表现
当你在 Node.js 中使用 pdf.js 处理 PDF 文件时,可能会看到如下错误信息:
ReferenceError: DOMMatrix is not defined
错误原因
DOMMatrix 是一个用于表示和操作 4x4 矩阵的 Web API,主要用于 2D 和 3D 转换。它在浏览器环境中是内置的,但在 Node.js 环境中并不存在。pdf.js 在处理 PDF 文件时需要使用 DOMMatrix 进行坐标转换和矩阵运算,因此在没有 DOMMatrix 的环境中就会报错。
解决方案
要解决这个问题,我们需要在 Node.js 环境中提供一个 DOMMatrix 的实现。推荐使用 @napi-rs/canvas 包,它提供了一个高性能的 DOMMatrix 实现。
步骤一:安装依赖
首先安装 @napi-rs/canvas 包:
npm install @napi-rs/canvas
步骤二:添加 DOMMatrix 定义
在你的代码中,在引入 pdf.js 之前添加以下代码:
import { DOMMatrix } from '@napi-rs/canvas';
if (typeof global.DOMMatrix === 'undefined') {
// @ts-ignore
global.DOMMatrix = DOMMatrix;
}
代码解释
- 导入 DOMMatrix:从
@napi-rs/canvas包中导入 DOMMatrix 类 - 全局检查:检查全局对象中是否已经定义了 DOMMatrix
- 全局赋值:如果没有定义,将导入的 DOMMatrix 赋值给 global.DOMMatrix
- TypeScript 忽略:使用
@ts-ignore注释避免 TypeScript 类型检查报错
完整示例
以下是一个完整的使用示例:
// 首先设置 DOMMatrix
import { DOMMatrix } from '@napi-rs/canvas';
if (typeof global.DOMMatrix === 'undefined') {
// @ts-ignore
global.DOMMatrix = DOMMatrix;
}
// 然后引入和使用 pdf.js
import * as pdfjsLib from 'pdfjs-dist';
// 设置 pdf.js worker
pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.js';
async function readPdf(pdfData) {
const loadingTask = pdfjsLib.getDocument({data: pdfData});
const pdf = await loadingTask.promise;
// 获取第一页
const page = await pdf.getPage(1);
// 获取文本内容
const textContent = await page.getTextContent();
return textContent;
}
export { readPdf };
注意事项
- 顺序重要:确保在引入 pdf.js 之前定义 DOMMatrix
- Node.js 版本:
@napi-rs/canvas需要 Node.js 14 或更高版本 - 系统依赖:在某些系统上可能需要安装额外的图形库依赖
- 性能考虑:
@napi-rs/canvas提供了原生性能,适合生产环境使用
替代方案
除了使用 @napi-rs/canvas,还有其他一些替代方案:
- canvas:较老的 canvas 实现,性能相对较低
- 自定义实现:可以自己实现一个简单的 DOMMatrix 类
- jsdom:引入完整的 DOM 环境,但较重
总结
通过使用 @napi-rs/canvas 包并在全局定义 DOMMatrix,可以有效解决 Node.js 环境中 pdf.js 的 DOMMatrix 未定义问题。这种方法简单高效,并且提供了良好的性能表现,是目前推荐的解决方案。
记住,在处理任何需要在 Node.js 中使用浏览器特有 API 的情况时,都可以考虑类似的解决方案:找到合适的 Node.js 实现,并在全局范围内定义它。