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.34k stars 881 forks source link

Is there a way to async load PDF.js similar to pdf.worker.js? PDF.js is about 200kb, which is too large for me. #1710

Open margintopt opened 8 months ago

margintopt commented 8 months ago

Before you start - checklist

Description

// pdj.ts in react-pdj

import * as pdfjsModule from 'pdfjs-dist';

const pdfjs = ( 'default' in pdfjsModule ? pdfjsModule['default'] : pdfjsModule ) as typeof pdfjsModule;

export default pdfjs;

Proposed solution

external script load pdf.js

Alternatives

No response

Additional information

No response

wojtekmaj commented 8 months ago

There's no direct way of doing this in v7. It will be possible with v8 as pdf.js 4.x supports it. Until then, perhaps lazy load the entire component?

margintopt commented 8 months ago

There's no direct way of doing this in v7. It will be possible with v8 as pdf.js 4.x supports it. Until then, perhaps lazy load the entire component?

Can I clone the library myself and then use webpack external to reduce the size of the pdfjs part?

wojtekmaj commented 8 months ago

I guess you could! I don't know much about this process, but react-pdf is open source and everything is allowed, feel welcome to experiment!

github-actions[bot] commented 5 months ago

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this issue will be closed in 14 days.

nikischin commented 4 months ago

I implemented the complete component as an asynchronous import within a Suspense and it works well and keeps my package size small. Not sure if this satisfies your needs though let me know if you need some code sample.

StevenRasmussen commented 3 months ago

@nikischin - Any chance you're able to share that code?

nikischin commented 3 months ago

Sure! Basically like this:

const PDFViewer = React.lazy(()=> import('./PDFViewer'));
export interface URLPDFViewerProps { url?: string, orientation?: 'portrait' | 'landscape' }

export default function URLPDFViewer (props: URLPDFViewerProps) {
    return (
        <Suspense fallback={<Spinner animation='border' />}>
            <PDFViewer {...props} />
        </Suspense>
    );
}
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
    'pdfjs-dist/build/pdf.worker.min.mjs',
    import.meta.url,
).toString();

export interface URLPDFViewerProps { url?: string, orientation?: 'portrait' | 'landscape' }

export default function PDFViewer ({ url, orientation }: URLPDFViewerProps) {
    return (
        <Document
            file={url}
            loading={<div><Spinner animation='grow' /></div>}
        >
            <Page
                height={orientation === 'portrait' ? 360 : undefined}
                width={orientation === 'portrait' ? undefined : 360}
            />
        </Document>
    );
}