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

Webpack entry point doesn't work with create-react-app on newest react-scripts 5.0.0 #912

Closed
3 of 4 tasks
franjaviersans opened this issue Dec 20, 2021 · 19 comments
Closed
3 of 4 tasks
Assignees
Labels
question Further information is requested

Comments

@franjaviersans
Copy link

franjaviersans commented Dec 20, 2021

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

I'm trying to use esm/entry.webpack to enable the worker with create-react-app 5.0.0 and the application is not being able to build due to heap allocation problems.

Steps to reproduce

  1. Create new create-react-app with create-react-app ensuring that it uses react-scripts 5.0.0
  2. Install react-pdf 5.6.0
  3. Add minimal code an import react-pdf with webpack.entry (see example code).

Expected behavior

Application builds and is able to run

Actual behavior

Fails to build with the following error:

> test-app@0.1.0 build
> react-scripts build

Creating an optimized production build...

<--- Last few GCs --->

[138110:0x5989090]    41304 ms: Scavenge 4028.1 (4116.0) -> 4021.2 (4115.8) MB, 5.7 / 0.0 ms  (average mu = 0.236, current mu = 0.152) allocation failure 
[138110:0x5989090]    41313 ms: Scavenge 4030.8 (4118.7) -> 4022.9 (4134.3) MB, 4.9 / 0.0 ms  (average mu = 0.236, current mu = 0.152) allocation failure 
[138110:0x5989090]    44505 ms: Mark-sweep 4042.4 (4138.5) -> 4021.9 (4136.0) MB, 3182.9 / 0.0 ms  (average mu = 0.186, current mu = 0.130) allocation failure scavenge might not succeed


<--- JS stacktrace --->

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0xb02ec0 node::Abort() [/usr/local/bin/node]
 2: 0xa181fb node::FatalError(char const*, char const*) [/usr/local/bin/node]
 3: 0xced88e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
 4: 0xcedc07 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
 5: 0xea5ea5  [/usr/local/bin/node]
 6: 0xea6986  [/usr/local/bin/node]
 7: 0xeb48be  [/usr/local/bin/node]
 8: 0xeb5300 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/bin/node]
 9: 0xeb827e v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
10: 0xe796aa v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [/usr/local/bin/node]
11: 0x11f2e86 v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [/usr/local/bin/node]
12: 0x15e7879  [/usr/local/bin/node]

Additional information

Here is the package.json content:


{
  "name": "test-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.1",
    "@testing-library/react": "^12.1.2",
    "@testing-library/user-event": "^13.5.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-pdf": "^5.6.0",
    "react-scripts": "5.0.0",
    "web-vitals": "^2.1.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Here is a small code used:


import "./App.css";
import { Document, Page } from "react-pdf/dist/esm/entry.webpack";
import React, { useState } from "react";

function PDFDocument() {
  const [numPages, setNumPages] = useState(null);
  const [pageNumber] = useState(1);

  function onDocumentLoadSuccess({ numPages }) {
    setNumPages(numPages);
  }

  return (
    <div>
      <Document
        file="https://www.soundczech.cz/temp/lorem-ipsum.pdf"
        onLoadSuccess={onDocumentLoadSuccess}
      >
        <Page pageNumber={pageNumber} />
      </Document>
      <p>
        Page {pageNumber} of {numPages}
      </p>
    </div>
  );
}

function App() {
  return (
    <div className="App">
      <PDFDocument />
    </div>
  );
}

export default App;

Environment

- **React-PDF version**: 5.6.0
- **React version**: 17.0.2
- **Webpack version (if applicable)**: 5.65.0 (installed by create-react-app)
@franjaviersans franjaviersans added the bug Something isn't working label Dec 20, 2021
@martenrichter
Copy link

I am not using react-pdf, but the underlying pdfjs library and I ran into the same issue, when switching to react-scripts@5.0.0 .
So it is probably more a problem with react-scrips itself.
I found a similar issue in older react-scripts versions over a year ago, turning off the source map generation in packages.json e.g. "GENERATE_SOURCEMAP=false react-scripts start" does for me the trick. But it would be good, if this will only apply to pdfjs. I will file an issue on react-scripts directly.

@martenrichter
Copy link

See also also #facebook/create-react-app/issues/8096 and #react-pdf/issues/498#issuecomment-566948710

@franjaviersans
Copy link
Author

It seems that it is related to loading the webworker itself, as it is too big and it fails creating the sourcemap. I don't really like the option of disabling the sourcemap, but it seems that it is the only option at the moment

@martenrichter
Copy link

I also do not like it. I have also found older solutions, where transpiling using babbel for the worker was deactivated. But I found no way how to do this without ejecting create react.

@MrEmanuel
Copy link

MrEmanuel commented Jan 12, 2022

I'm also running in to this problem using react-scripts@5.0.0 and react-pdf@5.6.0. I have a CRA app, following the webpack default implementation.

The only way I found to get around it is setting GENERATE_SOURCEMAP=false, but this isn't a long-term solution since I need the source maps.

Thanks for an otherwise awesome library!

@lorenzoalfieri
Copy link

The problem lie in the last update of react-scripts. It update webpack in version > 5, and in that version webpack don't polifyll by default nodejs core modules, used by react pdf. React team is working on it, and there is a good thread on it here : facebook/create-react-app#11756

And the current way to fix the issue : facebook/create-react-app#11756 (comment) and under

@franjaviersans
Copy link
Author

@lorenzoalfieri why would you say that it has to do with the polifyll? Which specific polifyll is it missing to be able to load the worker?

I can see that for the @reat-pdf/render it needs several polifylls, but I'm not quite sure if it is the same case for loading the worker

@albireox
Copy link

I agree this doesn't seem to be related to the change in how webpack 5 handles polifylls. I found this SO that seems relevant. Changing my script to use react-scripts --max_old_space_size=4096 seem to have some effect, if only in it taking longer to fail, but after trying with 4096, 8192, and 16384 I could not manage to make it work.

For now the only option that seems to work is using GENERATE_SOURCEMAP=false.

@martenrichter
Copy link

@albireox: I also tried this with no luck. The only thing, which could work was an idea, which suggested excluding the webworker file from transpiling, but either required ejecting react or was really complicated.

@wojtekmaj
Copy link
Owner

wojtekmaj commented Jan 17, 2022

Looks like this is caused by default create-react-app Webpack configuration parsing node_modules using Babel by default. React-PDF, more specifically its direct dependency pdfjs-dist, is particularly heavy, causing the out of memory error.

Related: facebook/create-react-app#8096

@wojtekmaj wojtekmaj added question Further information is requested and removed bug Something isn't working labels Jan 17, 2022
@franjaviersans
Copy link
Author

So, I was playing around with the source code and I found a potential solution. The import of the webworker could be modified to:

import pdfjsWorker from "!!file-loader!pdfjs-dist/legacy/build/pdf.worker";

adding !! at the beginning will disable all configured loader according to https://webpack.js.org/concepts/loaders/#inline

Probably, the CRA is adding some preLoaders or postLoaders that generates the source map

@wojtekmaj
Copy link
Owner

wojtekmaj commented Jan 19, 2022

Nice find @franjaviersans!

Technically, file-loader is deprecated in Webpack 5 in favor of asset modules.

This led me to the following section: https://webpack.js.org/guides/asset-modules/#url-assets

It appears like what we could do here for Webpack 5 would be very similar if not identical to our new Parcel 2 loader:

pdfjs.GlobalWorkerOptions.workerSrc = new URL('npm:pdfjs-dist/legacy/build/pdf.worker.entry.js', import.meta.url);

So in f213e54 that's exactly what I did.

I just tested it though and it doesn't seem to fix the underlying issue though - CRA still does something that causes out of memory bug.

@franjaviersans
Copy link
Author

Yes, I was also considering using worker-loader, but it is also deprecated acording to https://webpack.js.org/guides/web-workers/.

I did try loading with:

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

But we still get the memory issue

wojtekmaj added a commit that referenced this issue Jan 19, 2022
wojtekmaj added a commit that referenced this issue Jan 19, 2022
@wojtekmaj
Copy link
Owner

wojtekmaj commented Jan 19, 2022

Official recommendation

README was updated to include Create React App 5 instructions. Please have a read.
Spoiler alert: they are very similar to Standard instructions.

https://github.com/wojtekmaj/react-pdf#create-react-app

A full working sample repo has been also added in #923:

https://github.com/wojtekmaj/react-pdf/tree/main/sample/create-react-app-5

wojtekmaj added a commit that referenced this issue Jan 19, 2022
wojtekmaj added a commit that referenced this issue Jan 19, 2022
@wojtekmaj wojtekmaj self-assigned this Jan 19, 2022
@albireox

This comment has been minimized.

@wojtekmaj

This comment has been minimized.

@albireox

This comment has been minimized.

@wojtekmaj

This comment has been minimized.

@albireox

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

6 participants