wojtekmaj / react-pdf

Display PDFs in your React app as easily as if they were images.
https://projects.wojtekmaj.pl/react-pdf
MIT License
9.46k stars 886 forks source link

Server Error TypeError: url.replace is not a function #1554

Closed ashwinj984 closed 1 year ago

ashwinj984 commented 1 year ago

Before you start - checklist

Description

import { useState } from 'react';
import { Document, Page, pdfjs } from 'react-pdf';
import { Logger } from '@/lib/logger';
import { Screens } from '@/pages/constants';

import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
import 'react-pdf/dist/esm/Page/TextLayer.css';
//pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.js`;

pdfjs.GlobalWorkerOptions.workerSrc = new URL(
  'pdfjs-dist/build/pdf.worker.min.js',
  import.meta.url
).toString();
Screenshot 2023-07-11 at 5 24 01 PM

Steps to reproduce

Simply I have just added the code and when I am refreshing my development environment it is throwing this error.

Expected behavior

As per the documentation this code should work but it is throwing error.

pdfjs.GlobalWorkerOptions.workerSrc = new URL(
  'pdfjs-dist/build/pdf.worker.min.js',
  import.meta.url
).toString();

Actual behavior

It should not throw the error as it does not when we use cdn.

Additional information

No response

Environment

vdo9 commented 1 year ago

I am having an issue with setting up the web worker as well when testing in Jest. I receive this error: SyntaxError: Cannot use 'import.meta' outside a module

wojtekmaj commented 1 year ago

@BlankTurbo You didn't give me too many info to work with, but if I have to guess, you're trying to render React-PDF on the server side which doesn't make a lot of sense, because you can't stream canvas over the network anyway.

wojtekmaj commented 1 year ago

@vdo9 If you're using ESM modules, I'd discourage you from using Jest altogether. It has numerous problems with ESM modules handling.

Personally, I was not able to make it work well for my use case and have decided to move on to more modern Vitest. Migrating multiple repositories took me less time than trying to debug Jest bugs in one.

Alternatively, you could:

ashwinj984 commented 1 year ago

@BlankTurbo You didn't give me too many info to work with, but if I have to guess, you're trying to render React-PDF on the server side which doesn't make a lot of sense, because you can't stream canvas over the network anyway.

@wojtekmaj I am using a monorepo, my node_modules where my react-pdf and pdfjs-dist file are, not in the folder in which I am working, When I am using a cdn it is working completely fine but when I am approaching it as per the documentation method to use it from my node_modules rather than using the cdn then the props which I am passing in the new URL(x, y) are not able to make a proper url out of it, and we are giving it to a string it is throwing the error that url.replace is not a function.

I wanted to basically know if there can be a different approach to this?

As you correctly mentioned that we can't stream canvas over the network anyway, but we somehow send images and svg files right over the server and user it in out web-app, So if there is any way to do the same with the 'pdfjs-dist/build/pdf.worker.min.js' file.

Browser : Chrome Version 114.0.5735.198 (Official Build) (arm64) React-pdf version : 7.1.2 React-version: 18.1.0

My 'pdfjs-dist/build/pdf.worker.min.js' is relatively at this ../../../../../node_modules/pdfjs-dist/build/pdf.worker.min.jsposition from the place of import.meta.url. When I am using this, it is throwing me Warning: Setting up fake worker.. If I am trying to copy the file 'pdfjs-dist/build/pdf.worker.min.js' and use it my repo it is throwing again the same warning.

wojtekmaj commented 1 year ago

If you manually copied the file over and it's still giving you Warning: Setting up fake worker… message it means that the path you specified was not correct. Check the Network tab in your browser to see where the pdf.worker.min.js file is being requested from, compare to where it actually is, and debug it this way.

ashwinj984 commented 1 year ago

If you manually copied the file over and it's still giving you Warning: Setting up fake worker… message it means that the path you specified was not correct. Check the Network tab in your browser to see where the pdf.worker.min.js file is being requested from, compare to where it actually is, and debug it this way.

Found out the solution using this approach Thanks a lot!

ashwinj984 commented 1 year ago

I have one more issue which I faced recently not that big, that I will raise it in another issue, tagging it here only.

When I was using react-pdf 6.2.2 version my code was working perfectly fine, recently when I updated my version to 7.1.2 it is not working on deployment. What error it is showing on AWS Amplify is Error is: build size exceeding amplify supported size 200MB.. Is there any bigger change in react-pdf 7.1.2 that this error is occurring because it does not use to occur before? Is there any way that I update my version too and this error does not occur too?

wojtekmaj commented 1 year ago

Seems related to #1504.

The direct cause appears to be pdfjs-dist update. These are always fun.

praveengoswami1996 commented 9 months ago

If you manually copied the file over and it's still giving you Warning: Setting up fake worker… message it means that the path you specified was not correct. Check the Network tab in your browser to see where the pdf.worker.min.js file is being requested from, compare to where it actually is, and debug it this way.

Found out the solution using this approach Thanks a lot!

Could you please share the solution, What you did? I am still unable to figure it out. I am also facing the same issue.

ashwinsquadstack commented 9 months ago

If you manually copied the file over and it's still giving you Warning: Setting up fake worker… message it means that the path you specified was not correct. Check the Network tab in your browser to see where the pdf.worker.min.js file is being requested from, compare to where it actually is, and debug it this way.

Found out the solution using this approach Thanks a lot!

Could you please share the solution, What you did? I am still unable to figure it out. I am also facing the same issue.

@praveengoswami1996 Just use the correct file location it will work.

For me when I did it like this pdfjs.GlobalWorkerOptions.workerSrc = new URL( '../../../../../node_modules/pdfjs-dist/build/pdf.worker.min.js', import.meta.url ).toString();

It worked because the location of my pdf.worker.min.js relative to the file where I was adding it was '../../../../../node_modules/pdfjs-dist/build/pdf.worker.min.js' this.

For me it worked like this because I use a monorepo and node_modules are hoisted and they were not inside my root folder. So do check the location of file pdf.worker.min.js.

Try this your issue should get resolved.

praveengoswami1996 commented 9 months ago

If you manually copied the file over and it's still giving you Warning: Setting up fake worker… message it means that the path you specified was not correct. Check the Network tab in your browser to see where the pdf.worker.min.js file is being requested from, compare to where it actually is, and debug it this way.

Found out the solution using this approach Thanks a lot!

Could you please share the solution, What you did? I am still unable to figure it out. I am also facing the same issue.

@praveengoswami1996 Just use the correct file location it will work.

For me when I did it like this pdfjs.GlobalWorkerOptions.workerSrc = new URL( '../../../../../node_modules/pdfjs-dist/build/pdf.worker.min.js', import.meta.url ).toString();

It worked because the location of my pdf.worker.min.js relative to the file where I was adding it was '../../../../../node_modules/pdfjs-dist/build/pdf.worker.min.js' this.

For me it worked like this because I use a monorepo and node_modules are hoisted and they were not inside my root folder. So do check the location of file pdf.worker.min.js.

Try this your issue should get resolved.

Thanks Ashwin!! I appreciate your response. It perfectly worked for me. Thanks alot.

muboshers commented 7 months ago

useEffect(() => { pdfjs.GlobalWorkerOptions.workerSrc = new URL( 'pdfjs-dist/build/pdf.worker.js', import.meta.url, ).toString(); }, []);

problem statement like this because next js can not render outside of i just wrap pdf.js config in app tsx like this and problem fix

wojtekmaj commented 6 months ago

A better idea than useEffect appears to be:

if (typeof window !== 'undefined') {
  pdfjs.GlobalWorkerOptions.workerSrc = new URL(
    'pdfjs-dist/build/pdf.worker.min.js',
    import.meta.url,
  ).toString();
}

This would prevent the code from running on the server, while still running before render on the client.