Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Console error "Setting up fake worker failed" while using in React #12066

Closed
yummyelin opened this issue Jul 7, 2020 · 13 comments
Closed

Console error "Setting up fake worker failed" while using in React #12066

yummyelin opened this issue Jul 7, 2020 · 13 comments
Labels

Comments

@yummyelin
Copy link

Attach (recommended) or Link to PDF file here:
https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf

Configuration:

  • Web browser and its version: Chrome 83.0.4103.116
  • Operating system and its version: MacOS 10.14.6
  • PDF.js version: 2.4.456
  • Is a browser extension: No

Steps to reproduce the problem:

  1. Using credit-react-app to create a react project
    https://github.com/facebook/create-react-app
    npm init react-app my-app
  2. Install pdfjs-dist package
    npm install pdfjs-dist --save
  3. Import package and copy example code to App.js (https://github.com/mozilla/pdf.js/blob/master/examples/node/getinfo.js
    https://mozilla.github.io/pdf.js/examples/index.html#interactive-examples for prev/next example)
import pdfjsLib from 'pdfjs-dist/es5/build/pdf.js';
...
pdfjsLib.GlobalWorkerOptions.workerSrc = '../node_modules/pdfjs-dist/build/pdf.worker.js';
...
pdfjsLib.getDocument(url);
  1. Run react project
    yarn start
  2. Console shows error
Uncaught SyntaxError: Unexpected token '<' pdf.js:11915 
Uncaught (in promise) Error: Setting up fake worker failed: "Cannot read property 'WorkerMessageHandler' of undefined".
    at pdf.js:11915

Screen Shot 2020-07-06 at 9 49 47 PM

What is the expected behavior? (add screenshot)
Worker is setting up correctly.

What went wrong? (add screenshot)
pdfjsWorker does not exist in window object, which causes 'WorkerMessageHandler' of undefined issue.
The switch statement started with case 0 -> case 3 -> case 6 -> case 8, ended up with catch() in _setupFakeWorker()

function setupFakeWorkerGlobal() {
...
case 8:
   return _context.abrupt("return", window.pdfjsWorker.WorkerMessageHandler);
...
}

Screen Shot 2020-07-06 at 9 50 15 PM

Screen Shot 2020-07-06 at 9 50 32 PM

Screen Shot 2020-07-06 at 10 01 58 PM

Link to a viewer (if hosted on a site other than mozilla.github.io/pdf.js or as Firefox/Chrome extension):
(Trying to push code to my github, but reproducing the issue is very straight forward if following the steps.
all functions are the same as example code. renderPage() etc.)

Screen Shot 2020-07-06 at 10 07 39 PM

Screen Shot 2020-07-06 at 10 10 11 PM

@Snuffleupagus
Copy link
Collaborator

Please see https://github.com/mozilla/pdf.js/blob/master/.github/CONTRIBUTING.md (emphasis mine):

If you are developing a custom solution, first check the examples at https://github.com/mozilla/pdf.js#learning and search existing issues. If this does not help, please prepare a short well-documented example that demonstrates the problem and make it accessible online on your website, JS Bin, GitHub, etc. before opening a new issue or contacting us in the Matrix room -- keep in mind that just code snippets won't help us troubleshoot the problem.

@yummyelin
Copy link
Author

@Snuffleupagus
Thanks, this is the github url, let me know if it works.
https://github.com/yummyelin/poc/tree/pdf-poc

@yummyelin
Copy link
Author

Hi, I don't know why, but looks like copy pdf.worker.js to my project's output folder, or use cdn worker will make the magic happen. Using the one from node_modules/ doesn't work.

 // pdfjsLib.GlobalWorkerOptions.workerSrc = '../node_modules/pdfjs-dist/build/pdf.worker.js';
  pdfjsLib.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.1.266/pdf.worker.js`;

https://github.com/wojtekmaj/react-pdf#create-react-app

@ziiyan
Copy link

ziiyan commented Jul 27, 2020

Hi, I don't know why, but looks like copy pdf.worker.js to my project's output folder, or use cdn worker will make the magic happen. Using the one from node_modules/ doesn't work.

 // pdfjsLib.GlobalWorkerOptions.workerSrc = '../node_modules/pdfjs-dist/build/pdf.worker.js';
  pdfjsLib.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.1.266/pdf.worker.js`;

https://github.com/wojtekmaj/react-pdf#create-react-app

Hi, the same problem happened in my project. I guess it may be related to webpack moudle, but I'm not sure. Do you have any solutions now? (I have to avoid using cdn)

@pedro-surf
Copy link

pedro-surf commented Aug 16, 2020

Hi, does anybody know how to render Uint8Array format within create-react-app?
At this point I have no console errors, only an empty white screen. The file data is being correctly passed.

My React component looks like this:

import React, { useEffect, useState, createRef } from "react";
import * as pdfjs from "pdfjs-dist";
import { DocViewerProps } from "../../interfaces";
pdfjs.GlobalWorkerOptions.workerSrc = '//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js';

const DocViewer: React.FC<DocViewerProps> = ({ docData }) => {
  const [width, setWidth] = useState(0);
  const [height, setHeight] = useState(0);
  let fragmentRef = createRef<HTMLCanvasElement>();

  useEffect(() => {
    const viewDocument = async (docData) => {

      let loadingTask = pdfjs.getDocument({ data: docData });

      const pdfDocument = await loadingTask.promise;

      await pdfDocument.dataLoaded;

      const pdfPage = await pdfDocument.getPage(1);

      let viewport = pdfPage.getViewport({ scale: 1.0 });

      if (viewport && viewport.width && viewport.height) {
        console.dir(viewport);
        const { height, width } = viewport;
        setWidth(width);
        setHeight(height);
      }

      if (fragmentRef.current) {
        let canvasContext = fragmentRef.current.getContext("2d");
        if (canvasContext) {
          console.log("context has been set");
          await pdfPage.render({ canvasContext, viewport }).promise;
        }
      }
    };
    if (docData && fragmentRef) {
      console.dir(docData);
      viewDocument(docData);
    }
  }, [docData, fragmentRef]);

  return <canvas width={width} height={height} ref={fragmentRef} />;
};

export default DocViewer;

https://stackoverflow.com/questions/63432774/how-to-render-documents-with-pdf-js-and-cra

@Snuffleupagus
Copy link
Collaborator

Given that we know nothing about React here, is it meaningful to keep this issue open when we unfortunately cannot help?
/cc @timvandermeij

@joachimvandenabeele
Copy link

Hi, I don't know why, but looks like copy pdf.worker.js to my project's output folder, or use cdn worker will make the magic happen. Using the one from node_modules/ doesn't work.

 // pdfjsLib.GlobalWorkerOptions.workerSrc = '../node_modules/pdfjs-dist/build/pdf.worker.js';
  pdfjsLib.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.1.266/pdf.worker.js`;

https://github.com/wojtekmaj/react-pdf#create-react-app

Hi, the same problem happened in my project. I guess it may be related to webpack moudle, but I'm not sure. Do you have any solutions now? (I have to avoid using cdn)

Hi,
I had the same issue, but managed to solve it. It doesn't really have anything to do with webpack, but you do need to change your webpack configuration for it to work. Normally when you use the create-react-app it allows you to import files from the node_modules folder, however setting the workerSrc as in the following line doesn't work.
pdfjsLib.GlobalWorkerOptions.workerSrc = '../node_modules/pdfjs-dist/build/pdf.worker.js';
The reason for this is that you don't use an actual loader to load this file, we pass a path and at runtime a worker is created from this path, but at runtime this file is nowhere to be found and the path also doesn't exist.. To solve this you can make use of webpack its asset modules. In your webpack configuration you will need to adapt some things in your module -> rules.

  • Exclude the worker file from your normal .js/.ts loader (probably the babel-loader) so that when you later import it, it is not treated as your normal js files and transpiled by babel (because you use a file that was build already) , see the exclude path:
    { test: /\.(js|mjs|jsx|ts|tsx)$/, include: paths.appSrc, exclude: /pdfjs-dist\/build\/pdf\.worker\.js$/, loader: require.resolve('babel-loader'), ... }
    Inside exclude we don't prepend with node_modules as we will import it as 'pdfjs-dist/build/pdf.worker.js' later.

  • Add an asset loader for this specific file like this:
    { test: [/pdfjs-dist\/build\/pdf\.worker\.js$/], type: 'asset/resource' },

  • Next import the workerSrc in the file where you have to specify it:
    import workerSrc from 'pdfjs-dist/build/pdf.worker.js'

  • Use workerSrc that you just imported and assign it:
    pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc

This works when running it locally, haven't tested this yet when running on a live environment.
Hope this helps,

Kind regards

@hdsuperman
Copy link

With React:

import workerSrc from 'pdfjs-dist/build/pdf.worker.entry';
pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;

@ogiovanniruiz
Copy link

Anybody have a solution for this in angular?

@sky4564
Copy link

sky4564 commented Aug 16, 2023

With Vue :

const pdfjsLib = await import('pdfjs-dist')
const workerSrc = await import('pdfjs-dist/build/pdf.worker.entry')
pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc

@mr-chandan
Copy link

Did anyone get solution ?

@E-mo8
Copy link

E-mo8 commented Nov 26, 2023

@yummyelin
In my case the fix was to change from: const pdfjs = require("pdfjs-dist/legacy/build/pdf.js");
to : const pdfjs = require ("pdfjs-dist");

@IzykGit
Copy link

IzykGit commented Feb 10, 2024

I am having the same issue right now and I am pulling my hair out as I have been stuck on this for several hours now.

I have split my code into two separate files. The fetching from an S3 bucket and then displaying the PDF.

But for some reason when I combine the two files where I am both fetching from my S3 bucket and displaying the pdf on the page it works completely fine?

Obviously I can't do something like this because of security reasons but its like when I make a separate api file to fetch from my s3 bucket and then pass that to react-pdf in a different file it completely breaks.

pdf.worker.min.db5d8e2a.js:22 Uncaught ReferenceError: exports is not defined at pdf.worker.min.db5d8e2a.js:22:23

app-index.js:35 Warning: Error: Setting up fake worker failed: "Cannot read properties of undefined (reading 'WorkerMessageHandler')".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests