简体   繁体   English

创建 React 应用程序 - 如何将 pdf.worker.js 文件从 pdfjs-dist/build 复制到项目的 output 文件夹?

[英]Create react app - how to copy pdf.worker.js file from pdfjs-dist/build to your project's output folder?

Since I can't use browser's pdf viewer in the.network where the app is going to be used, I am testing a react-pdf package for loading PDF's with React.由于我无法在将要使用该应用程序的.network 中使用浏览器的 pdf 查看器,因此我正在测试react-pdf package 以使用 React 加载 PDF。 I have made a component where I am sending a url of my PDF that I get from backend:我制作了一个组件,我在其中发送我从后端获得的 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;

But, on opening the PDFViewer I get an error但是,在打开 PDFViewer 时出现错误

Error: Setting up fake worker failed: "Cannot read property 'WorkerMessageHandler' of undefined"错误:设置假工作者失败:“无法读取未定义的属性‘WorkerMessageHandler’”

In documentation it says that you should set up service worker and that the recommended way is to do that with CDN:在文档中它说你应该设置服务工作者并且推荐的方法是使用 CDN 来做到这一点:

import { pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js`;

But, I can't use CDN links for my project, and in the documentation it also says:但是,我不能为我的项目使用 CDN 链接,并且在文档中它还说:

Create React App uses Webpack under the hood, but instructions for Webpack will not work. Create React App 在后台使用 Webpack,但 Webpack 的说明将不起作用。 Standard instructions apply.适用标准说明。 Standard (Browserify and others) If you use Browserify or other bundling tools, you will have to make sure on your own that pdf.worker.js file from pdfjs-dist/build is copied to your project's output folder.标准(Browserify 和其他)如果您使用 Browserify 或其他捆绑工具,您必须自己确保将 pdfjs-dist/build 中的 pdf.worker.js 文件复制到项目的 output 文件夹中。

There are no instructions on how to do that with create-react-app.没有关于如何使用 create-react-app 执行此操作的说明。 How can I set this up locally then?那我该如何在本地设置呢?

Install pdfjs-dist安装pdfjs-dist

import { Document, Page, pdfjs } from "react-pdf";
import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";

pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;

Reference: https://github.com/mozilla/pdf.js/issues/8305参考: https://github.com/mozilla/pdf.js/issues/8305

found a more efficient way of including the worker by including the library from the dependencies of react-pdf itself, this way you will never get a version mismatch like this The API version "2.3.45" does not match the Worker version "2.1.266"通过从 react-pdf 本身的依赖项中包含库找到了一种更有效的方法来包含工作人员,这样你就永远不会得到这样的版本不匹配API 版本“2.3.45”与工作人员版本“2.1”不匹配。 266"

if you install pdfjs-dist manually you will have to check react pdf dependency version on every build如果您手动安装 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;

see similar error on pdfjs library: https://github.com/mozilla/pdf.js/issues/10997在 pdfjs 库上看到类似的错误: https://github.com/mozilla/pdf.js/issues/10997

hope it helps people希望它可以帮助人们

You can install worker loader module for webpack:您可以为 webpack 安装工作加载程序模块:

npm install worker-loader --save-dev

Then use it inline where you are going to work with a worker:然后在您将与工人一起工作的地方使用它:

import SomeWorker from 'worker-loader?inline=true!../workers/some.worker'

const someWorker: Worker = new SomeWorker()

someWorker.postMessage(...)

I haven't tried this solution with react-pdf , but it might help.我没有用react-pdf尝试过这个解决方案,但它可能会有所帮助。

You may need to add types for TypeScript if you are using it:如果您使用它,您可能需要为 TypeScript 添加类型:

declare module 'worker-loader*' {
  class SomeWorker extends Worker {
    constructor()
  }

  export default SomeWorker
}

Just to add that in some .d.ts file in your project.只是将其添加到项目中的某些.d.ts文件中。

Install pdfjs-dist then use the webpack module:安装pdfjs-dist然后使用webpack模块:

import { pdfjs } from 'react-pdf'
import worker from 'pdfjs-dist/webpack'

pdfjs.GlobalWorkerOptions.workerSrc = worker

If your build process uses cli commands, (ie AWS buildspec), you can use this:如果您的构建过程使用 cli 命令(即 AWS buildspec),您可以使用:

mkdir -p build && cp./node_modules/pdfjs-dist/build/pdf.worker.js build

If you are in a corporate codebase environment and have little to no experience configuring WebPack, I wanted to share a little more info if (like me) you struggled with this for quite a long time.如果您在公司代码库环境中并且几乎没有配置 WebPack 的经验,如果(像我一样)您在此问题上挣扎了很长时间,我想分享更多信息。

My environment has several complicated WebPack config files (base, production, and development), and the resolution ended up being pretty simple but it escaped me for quite a while because I was unfamiliar with the complicated build process.我的环境有几个复杂的 WebPack 配置文件(基础、生产和开发),最终解决方案非常简单,但由于我不熟悉复杂的构建过程,所以我有一段时间没能解决它。

1) The Implementation 1) 实施

Quite simple, just as the docs recommend (I went with the minified file).很简单,就像文档推荐的那样(我使用的是缩小文件)。 Our React environment required me to use React-PDF@4.2.0, but there aren't any differences here.我们的 React 环境要求我使用 React-PDF@4.2.0,但这里没有任何区别。

import {Document, Page, pdfjs} from 'react-pdf'
pdfjs.GlobalWorkerOptions.workerSrc = 'pdf.worker.min.js'

Note: a previous solution recommended grabbing the source from the react-pdf node_modules folder, however, my codebase is setup to install dependencies separately somehow because when I npm install react-pdf, pdfjs-dist is also installed separately.注意:以前的解决方案建议从 react-pdf node_modules 文件夹中获取源代码,但是,我的代码库设置为以某种方式单独安装依赖项,因为当我npm install react-pdf 时,pdfjs-dist 也单独安装。 Regardless, this method did not work for my codebase (importing the worker as a variable) due to the way the project is built.无论如何,由于项目的构建方式,此方法不适用于我的代码库(将 worker 作为变量导入)。 The import command acted like it couldn't find the proper named export inside a node_modules folder.导入命令的行为就像它在 node_modules 文件夹中找不到正确命名的导出一样。 It was top-level or nothing.它是顶级的,或者什么都不是。

2) WebPack Config 2) WebPack 配置

Since I do not know WebPack at all, but found pretty easily that what I needed to do was take advantage of CopyWebpackPlugin , I searched through those existing dev and prod webpack config files, and found existing copy commands for JQuery and polyfill and added a new plugin to that array:由于我根本不知道 WebPack,但是很容易发现我需要做的是利用CopyWebpackPlugin ,我搜索了那些现有的开发和产品 webpack 配置文件,并找到了 Z6A2D7208853BEF37ED04F8795A88Z 的现有复制命令和添加了新的复制命令该数组的插件:

new CopyWebpackPlugin({from: 'node_modules/pdfjs-dist/build/pdf.worker.min.js})

I had to do this in multiples places in both config files as this large project has several entry point server files for the different services of the website.我必须在两个配置文件中的多个位置执行此操作,因为这个大型项目有多个用于网站不同服务的入口点服务器文件。

3) Inserting Script Tag to HTML Head 3) 将脚本标签插入 HTML 头

This was the crucial part I was missing.这是我错过的关键部分。 There was a "ComponentFactory" file whose job it was to insert chunks of html in the <head> and tail of the html file.有一个“ComponentFactory”文件,其工作是在 html 文件的<head>和尾部插入 html 块。 I wasn't used to something like this on small projects.我不习惯在小项目上做这样的事情。 So there, I simply copied what was already done for the jquery and polyfill, which included a string literal of the location of the assets folder the webpack was building out to.所以在那里,我只是复制了已经为 jquery 和 polyfill 完成的工作,其中包括 webpack 正在构建的资产文件夹位置的字符串文字。 In my case, that was something like "assets/v1/".就我而言,这类似于“assets/v1/”。 So the tag looked like this:所以标签看起来像这样:

<script src=`${STATIC_ASSETS_URL}/pdf.worker.min.js` defer></script>

It works perfectly, however I am still getting the "Setting Up a Fake Worker" but immediately after that, it loaded it successfully in console and checking the dev tools, it was using the proper file.它工作得很好,但是我仍然得到“设置一个假工人”,但在那之后,它立即在控制台中成功加载它并检查开发工具,它使用了正确的文件。 It's probably just a timing thing of the src set not running high enough in the code, but it was not effecting the outcome, so I let it go.这可能只是 src 集在代码中运行得不够高的时间问题,但它并没有影响结果,所以我让它 go。

(Sidebar, if you also get the "TT unknown function" (paraphrasing) error, that can be ignored. It's just a font issue with whatever PDF you are loading and is just a warning, not an error.) (侧边栏,如果您还收到“TT 未知函数”(释义)错误,可以忽略。这只是您正在加载的 PDF 的字体问题,只是一个警告,而不是错误。)

I was facing this issue once I had to use "react-pdf" from within a package. It was solved by importing the worker conditionally into the code:一旦我不得不在 package 中使用“react-pdf”,我就遇到了这个问题。通过有条件地将 worker 导入代码中解决了这个问题:

  1. Conditional import:有条件的进口:

 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') } }

  1. usage:用法:

 import { Document, Page, pdfjs } from 'react-pdf/dist/umd/entry.webpack' pdfjs.GlobalWorkerOptions.workerSrc = getWorker()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React 应用程序中 pdfjs-dist 的附加加载器? - Additional loader for pdfjs-dist in react app? pdfjs-dist package 构建过程中的问题 - pdfjs-dist package problem while build process 使用pdfjs-dist(PDFJS)中的TypeScript(TSX)中的方法导入名称空间和接口 - Importing namespace and interface with methods in TypeScript (TSX) in pdfjs-dist (PDFJS) 从gitlab将react.js应用程序/ dist文件夹部署到heroku - Deploy react.js app /dist folder to heroku from gitlab 如何从 Create React App /build 文件夹制作 npm 包? - How to make a npm package from Create React App /build folder? 如何在 Webpack 构建过程中将 React 应用程序中的 mockServiceWorker.js 文件复制到我的构建文件夹 - How copy down mockServiceWorker.js file in React application during Webpack build proces to my build folder 如何在基于 React 的项目中从我的页面创建 PDF 文件? - How to create a PDF file from my page in the React based project? 我创建了我的 react 应用程序并与 electron.js 连接。 现在如何将我的后端从服务器文件夹与电子连接 - I create a build of my react app and connected with electron.js. now how to connect my backend from server folder with electron 添加 Service Worker 以创建 React App 项目 - Add Service Worker to Create React App Project 如何在 create react 应用程序中从 service worker 范围中排除 url,而不必弹出? - How do I exclude url's from service worker scope in create react app, without having to eject?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM