[英]Create react app - how to copy pdf.worker.js file from pdfjs-dist/build to your project's output folder?
由於我無法在將要使用該應用程序的.network 中使用瀏覽器的 pdf 查看器,因此我正在測試react-pdf package 以使用 React 加載 PDF。 我制作了一個組件,我在其中發送我從后端獲得的 PDF 的 url:
import React, { useState } from 'react';
import { Document, Page } from 'react-pdf';
const PDFViewer = ({url}) => {
const [numPages, setNumPages] = useState(null);
const [pageNumber, setPageNumber] = useState(1);
function onDocumentLoadSuccess({ numPages }) {
setNumPages(numPages);
}
function onLoadError(error) {
console.log(error);
}
function onSourceError(error) {
console.log(error);
}
return (
<div>
<Document
file={window.location.origin + url}
onLoadSuccess={onDocumentLoadSuccess}
onLoadError={onLoadError}
onSourceError={onSourceError}
>
{[...Array(numPages).keys()].map((p) => (
<Page pageNumber={p + 1} />
))}
</Document>
</div>
);
};
export default PDFViewer;
但是,在打開 PDFViewer 時出現錯誤
錯誤:設置假工作者失敗:“無法讀取未定義的屬性‘WorkerMessageHandler’”
在文檔中它說你應該設置服務工作者並且推薦的方法是使用 CDN 來做到這一點:
import { pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js`;
但是,我不能為我的項目使用 CDN 鏈接,並且在文檔中它還說:
Create React App 在后台使用 Webpack,但 Webpack 的說明將不起作用。 適用標准說明。 標准(Browserify 和其他)如果您使用 Browserify 或其他捆綁工具,您必須自己確保將 pdfjs-dist/build 中的 pdf.worker.js 文件復制到項目的 output 文件夾中。
沒有關於如何使用 create-react-app 執行此操作的說明。 那我該如何在本地設置呢?
安裝pdfjs-dist
import { Document, Page, pdfjs } from "react-pdf";
import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;
通過從 react-pdf 本身的依賴項中包含庫找到了一種更有效的方法來包含工作人員,這樣你就永遠不會得到這樣的版本不匹配API 版本“2.3.45”與工作人員版本“2.1”不匹配。 266"
如果您手動安裝 pdfjs-dist,則必須在每個構建中檢查 react pdf 依賴版本
import { Document, Page, pdfjs } from "react-pdf";
import pdfjsWorker from "react-pdf/node_modules/pdfjs-dist/build/pdf.worker.entry";
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;
在 pdfjs 庫上看到類似的錯誤: https://github.com/mozilla/pdf.js/issues/10997
希望它可以幫助人們
您可以為 webpack 安裝工作加載程序模塊:
npm install worker-loader --save-dev
然后在您將與工人一起工作的地方使用它:
import SomeWorker from 'worker-loader?inline=true!../workers/some.worker'
const someWorker: Worker = new SomeWorker()
someWorker.postMessage(...)
我沒有用react-pdf
嘗試過這個解決方案,但它可能會有所幫助。
如果您使用它,您可能需要為 TypeScript 添加類型:
declare module 'worker-loader*' {
class SomeWorker extends Worker {
constructor()
}
export default SomeWorker
}
只是將其添加到項目中的某些.d.ts
文件中。
安裝pdfjs-dist
然后使用webpack
模塊:
import { pdfjs } from 'react-pdf'
import worker from 'pdfjs-dist/webpack'
pdfjs.GlobalWorkerOptions.workerSrc = worker
如果您的構建過程使用 cli 命令(即 AWS buildspec),您可以使用:
mkdir -p build && cp./node_modules/pdfjs-dist/build/pdf.worker.js build
如果您在公司代碼庫環境中並且幾乎沒有配置 WebPack 的經驗,如果(像我一樣)您在此問題上掙扎了很長時間,我想分享更多信息。
我的環境有幾個復雜的 WebPack 配置文件(基礎、生產和開發),最終解決方案非常簡單,但由於我不熟悉復雜的構建過程,所以我有一段時間沒能解決它。
1) 實施
很簡單,就像文檔推薦的那樣(我使用的是縮小文件)。 我們的 React 環境要求我使用 React-PDF@4.2.0,但這里沒有任何區別。
import {Document, Page, pdfjs} from 'react-pdf'
pdfjs.GlobalWorkerOptions.workerSrc = 'pdf.worker.min.js'
注意:以前的解決方案建議從 react-pdf node_modules 文件夾中獲取源代碼,但是,我的代碼庫設置為以某種方式單獨安裝依賴項,因為當我npm install
react-pdf 時,pdfjs-dist 也單獨安裝。 無論如何,由於項目的構建方式,此方法不適用於我的代碼庫(將 worker 作為變量導入)。 導入命令的行為就像它在 node_modules 文件夾中找不到正確命名的導出一樣。 它是頂級的,或者什么都不是。
2) WebPack 配置
由於我根本不知道 WebPack,但是很容易發現我需要做的是利用CopyWebpackPlugin
,我搜索了那些現有的開發和產品 webpack 配置文件,並找到了 Z6A2D7208853BEF37ED04F8795A88Z 的現有復制命令和添加了新的復制命令該數組的插件:
new CopyWebpackPlugin({from: 'node_modules/pdfjs-dist/build/pdf.worker.min.js})
我必須在兩個配置文件中的多個位置執行此操作,因為這個大型項目有多個用於網站不同服務的入口點服務器文件。
3) 將腳本標簽插入 HTML 頭
這是我錯過的關鍵部分。 有一個“ComponentFactory”文件,其工作是在 html 文件的<head>
和尾部插入 html 塊。 我不習慣在小項目上做這樣的事情。 所以在那里,我只是復制了已經為 jquery 和 polyfill 完成的工作,其中包括 webpack 正在構建的資產文件夾位置的字符串文字。 就我而言,這類似於“assets/v1/”。 所以標簽看起來像這樣:
<script src=`${STATIC_ASSETS_URL}/pdf.worker.min.js` defer></script>
它工作得很好,但是我仍然得到“設置一個假工人”,但在那之后,它立即在控制台中成功加載它並檢查開發工具,它使用了正確的文件。 這可能只是 src 集在代碼中運行得不夠高的時間問題,但它並沒有影響結果,所以我讓它 go。
(側邊欄,如果您還收到“TT 未知函數”(釋義)錯誤,可以忽略。這只是您正在加載的 PDF 的字體問題,只是一個警告,而不是錯誤。)
一旦我不得不在 package 中使用“react-pdf”,我就遇到了這個問題。通過有條件地將 worker 導入代碼中解決了這個問題:
export const getWorker = () => { try { return require('react-pdf/node_modules/pdfjs-dist/legacy/build/pdf.worker.entry.js') } catch () { return require('pdfjs-dist/legacy/build/pdf.worker.entry.js') } }
import { Document, Page, pdfjs } from 'react-pdf/dist/umd/entry.webpack' pdfjs.GlobalWorkerOptions.workerSrc = getWorker()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.