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

Can't resolve 'pdfjs-dist/build/pdf.worker.min.mjs in Nextjs 14 app router #1855

Open
4 tasks done
raibann opened this issue Aug 13, 2024 · 5 comments
Open
4 tasks done
Labels
bug Something isn't working

Comments

@raibann
Copy link

raibann commented Aug 13, 2024

Before you start - checklist

  • I followed instructions in documentation written for my React-PDF version
  • I have checked if this bug is not already reported
  • I have checked if an issue is not listed in Known issues
  • If I have a problem with PDF rendering, I checked if my PDF renders properly in PDF.js demo

Description

import { Box, CircularProgress, Pagination, Stack, Typography } from '@mui/material';
import React, { useState } from 'react';
import { DocumentText } from 'iconsax-react';
import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
import 'react-pdf/dist/esm/Page/TextLayer.css';
import { Document, Page, pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString();

const options = {
cMapUrl: '/cmaps/',
standardFontDataUrl: '/standard_fonts/',
};

/**

  • Comp
    /
    const CustPreviewPdf = ({ file, disablePage }: { file?: File | string; disablePage?: boolean }) => {
    /
    *
    • States
      */
      const [totalPages, setTotalPages] = useState(0);
      const [pageNumber, setPageNumber] = useState(1);

/**

  • Methods
    */
    const onDocumentLoadSuccess = ({ totalPages }: { totalPages: number }) => {
    setTotalPages(totalPages);
    };
    return (
    <>
    <Document
    file={file}
    onLoadSuccess={(value) => onDocumentLoadSuccess({ totalPages: value.numPages })}
    loading={}
    noData={
    <Stack direction={'column'} alignItems={'center'}>

    No PDF Imported

    }
    className={'disable-pdf-select'}
    options={options}
    {!disablePage && ( , page: number) => { setPageNumber(page); }} /> )}
</>

);
};

export default CustPreviewPdf;

Steps to reproduce

                                                                                           ^^^^^^
`----

Caused by:
0: failed to parse input file
1: Syntax Error

Build failed because of webpack errors
when I install react pdf version 9.1.0 it can't build.

Expected behavior

⨯ node_modules/pdfjs-dist/build/pdf.mjs (5448:0) @ eval
⨯ TypeError: Promise.withResolvers is not a function
at webpack_require (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/webpack-runtime.js:33:43)
at eval (./src/components/customs/media/CustPreviewPdf.tsx:17:67)
at (ssr)/./src/components/customs/media/CustPreviewPdf.tsx (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/app/new-document/page.js:642:1)
at webpack_require (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/webpack-runtime.js:33:43)
at eval (./src/app/new-document/components/qrcode/index.tsx:13:98)
at (ssr)/./src/app/new-document/components/qrcode/index.tsx (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/app/new-document/page.js:433:1)
at webpack_require (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/webpack-runtime.js:33:43)
at eval (./src/app/new-document/page.tsx:27:76)
at (ssr)/./src/app/new-document/page.tsx (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/app/new-document/page.js:543:1)
at webpack_require (/Users/raibann/Documents/ONLINEISP/PROJECTS/FRONTEND/next-document-tracking/.next/server/webpack-runtime.js:33:43)
at JSON.parse ()
null

Actual behavior

Additional information

Environment

  • Browser (if applicable):
  • React-PDF version:
  • React version:
  • Bundler name and version (if applicable):
@raibann raibann added the bug Something isn't working label Aug 13, 2024
@orlando-aidora
Copy link

Same here
it throws an error and the PDF is not rendered:

image

@UmairJibran
Copy link

this worked for me

@kristianeboe
Copy link

Check out this as well! Bun patch fixed it for me :D

vercel/next.js#65406 (comment)

https://bun.sh/docs/install/patch

@satyadalei
Copy link

I encountered the same error when using react-pdf in my Next.js (version 14) app during the build phase. It was working perfectly in development, but the error appeared during the production build.

WhatsApp Image 2024-08-29 at 10 59 42 PM

@UmairJibran made a valid point, and while his solution might work for some, it didn't solve the issue for me. I fixed by replacing the following line:

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

with this

pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;

I switched to using the CDN, as specified in the docs

Here is the screenshot

WhatsApp Image 2024-08-29 at 10 57 40 PM

@scaabel
Copy link

scaabel commented Sep 5, 2024

I've encountered the same error too.

Building on top of @satyadalei's solution.

You can download the CDN and put it in the public directory and call it like this.

import { Document, Page, pdfjs } from 'react-pdf'

pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.mjs

Additionally, you might run into this error [ERROR] Promise.withResolvers is not a function Stack trace:

So, you have to add the polyfill

// Polyfill
// NOTE: pdfjs-dist is throwing Promise.withResolvers is not a function
// This is a workaround to fix the issue
if (typeof Promise.withResolvers !== 'function') {
Promise.withResolvers = function <T>() {
  let resolve!: (value: T | PromiseLike<T>) => void
  let reject!: (reason?: any) => void
  const promise = new Promise<T>((res, rej) => {
    resolve = res
    reject = rej
  })
  return { promise, resolve, reject }
}
}

export {}

Make sure to declare the type in your declaration.d.ts

interface PromiseConstructor {
 withResolvers<T>(): {
   promise: Promise<T>
   resolve: (value: T | PromiseLike<T>) => void
   reject: (reason?: any) => void
 }
}

Your component should look something like this

import 'path/to/polyfill'
import { Document, Page, pdfjs } from 'react-pdf'
pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.mjs'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants