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

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)

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 8
  • Comments: 19 (5 by maintainers)

Commits related to this issue

Most upvoted comments

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

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

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 : https://github.com/facebook/create-react-app/issues/11756

And the current way to fix the issue : https://github.com/facebook/create-react-app/issues/11756#issuecomment-1002637667 and under