I am creating a PDF generator using the react-pdf package at https://react-pdf.org/. The process of converting the react-pdf components into a pdf blocks the main thread, so I would like to convert them on a separate Worker thread.
I am using create-react-app with worker-loader to recognize WebWorker files. I am having a hard time coming up with a way to import the react components into the Webworker and convert them using the pdf(Component).toBlob() method provided by react-pdf. The pdf(Component).toBlob() takes a react component as input and outputs the blob files, this means that the worker has to somehow be able to load the React component. The WebWorker works as expected when no React components are included.
I naively tried importing the React components into the WebWorker and tried running the conversion method:
pdf(<Component />).toBlob().then(blob=>{
...
})
which causes a module parse error:
Uncaught Error: Module parse failed: Unexpected token (14:8)
File was processed with these loaders:
* ./node_modules/eslint-loader/index.js
You may need an additional loader to handle the result of these loaders.
Any help would be extremely appreciated.
Edit:
I am using the create-react-app default webpack configuration with the addition of worker-loader which detects .worker.js
files and registers them as Webworker. I added the work-loader using the react-app-rewired package:
module.exports = function override(config, env) {
config.module.rules.push({
test: /\.worker\.js$/,
use: { loader: 'worker-loader' }
})
config.output['globalObject'] = 'this';
return config;
}
This answer is an extension of the discussion we had in the chat.
The issue at hand here is the .push()
from the override function. As stated in the MSDN documentation:
The push() method adds one or more elements to the end of an array and returns the new length of the array.
Effectively the config.module.rules.push()
is adding the loader at the end of the rules array, thus processing first the React code and then the worker.js
.
As Ali Zeaiter found out the solution was to use .unshift()
(cf. doc) instead of .push()
in order to prepend the loader to the rules array and thus processing first the worker.js
file.