feat(pdf-viewer): add postinstall script for pdfjs worker and simplify pdf rendering
This commit is contained in:
@@ -8,7 +8,8 @@
|
||||
"dev:ragflow": "pnpm -r --filter ragflow_web run dev",
|
||||
"build": "tsc -b && vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"postinstall": "node scripts/copy-pdfjs-worker.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.14.0",
|
||||
|
||||
28
public/pdfjs-dist/pdf.worker.min.mjs
Normal file
28
public/pdfjs-dist/pdf.worker.min.mjs
Normal file
File diff suppressed because one or more lines are too long
15
scripts/copy-pdfjs-worker.mjs
Normal file
15
scripts/copy-pdfjs-worker.mjs
Normal file
@@ -0,0 +1,15 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
const src = path.resolve('node_modules/pdfjs-dist/build/pdf.worker.min.mjs');
|
||||
const destDir = path.resolve('public/pdfjs-dist');
|
||||
const dest = path.join(destDir, 'pdf.worker.min.mjs');
|
||||
|
||||
try {
|
||||
fs.mkdirSync(destDir, { recursive: true });
|
||||
fs.copyFileSync(src, dest);
|
||||
console.log(`[pdfjs-dist] Worker copied to: ${dest}`);
|
||||
} catch (err) {
|
||||
console.error('[pdfjs-dist] Failed to copy worker:', err);
|
||||
process.exitCode = 1;
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
// 使用 pdf.js 在左侧容器中渲染 PDF 页面,支持自由滑动与页码定位
|
||||
import * as pdfjsLib from 'pdfjs-dist';
|
||||
// 使用 Vite 的资源 URL 解析,将 pdf.js 的模块 worker 转成可访问 URL
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
import pdfjsWorkerUrl from 'pdfjs-dist/build/pdf.worker.min.mjs?url';
|
||||
|
||||
// 采用模块 Worker,避免经典 worker 的 MIME/路径问题
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
const PDFJS_WORKER_MJS = '/pdfjs-dist/pdf.worker.min.mjs';
|
||||
// @ts-ignore
|
||||
pdfjsLib.GlobalWorkerOptions.workerPort = new Worker(pdfjsWorkerUrl, { type: 'module' });
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = PDFJS_WORKER_MJS;
|
||||
// @ts-ignore
|
||||
pdfjsLib.GlobalWorkerOptions.disableWorker = true;
|
||||
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import {
|
||||
Box,
|
||||
@@ -161,17 +159,11 @@ function ChunkParsedResult() {
|
||||
}
|
||||
try {
|
||||
const arrayBuffer = await documentFile.arrayBuffer();
|
||||
|
||||
const renderWithDoc = async (disableWorker: boolean) => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const task = pdfjsLib.getDocument({ data: arrayBuffer, disableWorker });
|
||||
const pdfDoc = await task.promise;
|
||||
|
||||
const container = pdfContainerRef.current;
|
||||
if (!container) return;
|
||||
container.innerHTML = '';
|
||||
|
||||
const renderPages = async (pdfDoc: any) => {
|
||||
container.innerHTML = '';
|
||||
// 根据容器宽度自适应缩放
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const containerWidth = Math.max(1, Math.floor(containerRect.width || container.clientWidth || 800));
|
||||
@@ -215,23 +207,26 @@ function ChunkParsedResult() {
|
||||
}
|
||||
};
|
||||
|
||||
// 尝试使用 Worker(优先模块,其次经典)
|
||||
try {
|
||||
// 优先使用 Worker 渲染
|
||||
await renderWithDoc(false);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const task = pdfjsLib.getDocument({ data: arrayBuffer });
|
||||
const pdfDoc = await task.promise;
|
||||
await renderPages(pdfDoc);
|
||||
setPdfRendered(true);
|
||||
} catch (err1) {
|
||||
console.error('PDF.js Worker 渲染失败,降级为主线程渲染。错误: ', err1);
|
||||
try {
|
||||
// Worker 不可用时,禁用 Worker 在主线程渲染
|
||||
await renderWithDoc(true);
|
||||
console.error('第一次渲染失败,尝试主线程渲染:', err1);
|
||||
// 失败则回退主线程
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const fallbackTask = pdfjsLib.getDocument({ data: arrayBuffer, disableWorker: true });
|
||||
const pdfDoc2 = await fallbackTask.promise;
|
||||
await renderPages(pdfDoc2);
|
||||
setPdfRendered(true);
|
||||
} catch (err2) {
|
||||
console.error('PDF.js 主线程渲染失败: ', err2);
|
||||
setPdfRendered(false);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('读取 PDF 文件数据失败: ', err);
|
||||
console.error('渲染 PDF 过程中发生错误: ', err);
|
||||
setPdfRendered(false);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user