Skip to content
This repository has been archived by the owner on Oct 19, 2022. It is now read-only.

Enable usage of react-pdf inside a web worker #3

Merged
merged 1 commit into from
Feb 13, 2022
Merged

Enable usage of react-pdf inside a web worker #3

merged 1 commit into from
Feb 13, 2022

Conversation

carlobeltrame
Copy link
Contributor

Thanks a lot for this shim! As I already mentioned in diegomura/react-pdf#1317, it has helped me to run react-pdf using vite, and even inside a Vue application.
In the meantime, we have started using web workers for rendering the PDFs for performance reasons. The approach from diegomura/react-pdf#464 has served as a basis there. However, I have had to add another shim, since in a web worker environment, window is not defined, but instead the global scope is called self.
This PR adds the fix I found to this library, in the safest way I could find. It should only have any effect if the code is currently running inside a web worker. We are able to transparently switch our implementation between running on the main thread and running in the worker, and both variants work fine with this small addition.

@carlobeltrame carlobeltrame mentioned this pull request Feb 12, 2022
54 tasks
@thekevinbrown
Copy link
Member

Looks great, thanks for the patch!

@thekevinbrown thekevinbrown merged commit f435b7b into exogee-technology:main Feb 13, 2022
@thekevinbrown
Copy link
Member

This is now published in v1.0.5. Let me know if you have any trouble!

@carlobeltrame carlobeltrame deleted the patch-1 branch February 13, 2022 23:25
carlobeltrame added a commit to carlobeltrame/ecamp3 that referenced this pull request Feb 17, 2022
Now that the content of our shim extension was merged in
exogee-technology/vite-plugin-shim-react-pdf#3
we can safely remove our own shimming.
carlobeltrame added a commit to carlobeltrame/ecamp3 that referenced this pull request Mar 18, 2022
Now that the content of our shim extension was merged in
exogee-technology/vite-plugin-shim-react-pdf#3
we can safely remove our own shimming.
@aclec
Copy link

aclec commented Apr 10, 2022

Hello, I used your method to render my pdf in a web worker.
However I cannot use "require" like you because an error is raised and by using "await import", I have the impression that my component is not imported because I have no error but my console.log afterwards the import never runs.

@carlobeltrame
Copy link
Contributor Author

carlobeltrame commented Apr 14, 2022

@aclec I have also had problems similar to what you describe, with Firefox not supporting dynamic imports of web worker scripts correctly, while in Chromium it worked fine. For now, I solved them by using vite-plugin-worker and using the worker-iife mode of that plugin: https://github.com/ecamp/ecamp3/blob/devel/frontend/src/components/print/print-react/generatePdf.js#L3
The iife part will generate an "immediately invoked function expression", which leads to the same behaviour as if I were using an async import, but with the added benefit that it works in Firefox.
The relevant but trivial vite config of that plugin: https://github.com/ecamp/ecamp3/blob/devel/frontend/vite.config.js#L17..L18

Additionally, I added import 'raf/polyfill' to get rid of some requestAnimationFrame-related warnings from React, which were popping up when using React in the worker.

Unfortunately, raf/polyfill also requires either global or window, so the fix I made in this PR here ended up not helping me. In other words: vite-plugin-shim-react-pdf modifies the code in react-pdf. Before importing react-pdf, I need to import React. Before React, I need to import raf/polyfill. And raf/polyfill already requires the global or window variable to be defined (I don't remember which one). So as a consequence, I still have to define window and global manually in my application: In this file, line 4 manually imports the extension I made in this PR, line 5 imports raf/polyfill and line 6 imports React and react-pdf.

I am also using Comlink to simplify the boilerplate code for communication between main thread and worker, but that should be optional.
Futher I have had some issues with fonts in the rendered PDF, so I had to make sure that Vite includes all required fonts in the production bundle, by importing all fonts in the main thread script.
Also, I had to be very careful not to import anything unexpected in the worker. E.g. in my case, Vue can never be imported in the worker, because Vue cannot run inside a worker as far as I am aware. As a consequence, my worker also cannot import any other packages that rely on Vue (Vuex, vue-i18n, ...).

This current setup works for me both during development and in a productive build, in Firefox, Chrome, Chromium, Edge and even Firefox mobile. Let me know if you need more explanations or if something is unclear.

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

Successfully merging this pull request may close these issues.

None yet

3 participants