Search code examples
reactjswebpackgatsbyreact-pdf

react-pdf library is giving error at gatsby build time


I am creating react product using gatsby. I am using react-pdf library. It is givining follwoing error at build time. How can I solve it? I used gatsby 3.3.0 version. and using react-pdf 5.2.0

D:\Project\public\render-page.js:137661
  window.requestAnimationFrame(resolve);

ReferenceError: window is not defined
    at D:\Project\public\render-page.js:40343:3
    at new Promise (<anonymous>)
    at Object../node_modules/pdfjs-dist/lib/web/ui_utils.js (D:\Project\public\render-page.js:4034
2:26)
    at __webpack_require__ (D:\Project\public\render-page.js:48664:42)
    at Object../node_modules/pdfjs-dist/lib/web/pdf_link_service.js (D:\Brisktech\Android\public\render-page
.js:39345:17)
    at __webpack_require__ (D:\Project\public\render-page.js:48664:42)
    at Module../node_modules/react-pdf/dist/esm/LinkService.js (D:\Project\public\render-page.js:4
4080:93)
    at __webpack_require__ (D:\Project\public\render-page.js:48664:42)
    at Module../node_modules/react-pdf/dist/esm/Document.js (D:\Project\public\render-page.js:4351
2:71)
    at __webpack_require__ (D:\Project\public\render-page.js:48664:42)
    at Module../node_modules/react-pdf/dist/esm/entry.webpack.js (D:\Brisktech\Android\public\render-page.js
:46550:67)
    at __webpack_require__ (D:\Project\public\render-page.js:48664:42)
    at Module../src/routes/default/index.js (D:\Project\public\render-page.js:7404:90)
    at __webpack_require__ (D:\Project\public\render-page.js:48664:42)
    at Object../.cache/_this_is_virtual_fs_path_/$virtual/sync-requires.js (D:\Brisktech\Android\public\rend
er-page.js:6740:116)
    at __webpack_require__ (D:\Project\public\render-page.js:48664:42)
D:\Project\public\render-page.js:40343
  window.requestAnimationFrame(resolve);
  ^
failed Building static HTML for pages - 2.931s

 ERROR #95313

Building static HTML failed

See our docs page for more info on this error: https://gatsby.dev/debug-html


  10 |
  11 | export default function _createClass(Constructor, protoProps, staticProps) {
> 12 |   if (protoProps) _defineProperties(Constructor.prototype, protoProps);
     | ^
  13 |   if (staticProps) _defineProperties(Constructor, staticProps);
  14 |   return Constructor;
  15 | }


  WebpackError: Call retries were exceeded

  - createClass.js:12
    [fitupme-app]/[@babel]/runtime/helpers/esm/createClass.js:12:1



error Command failed with exit code 1.

If I lower the version of react-pdf then It is working but giving warning. react-pdf: 4.2.0

 ERROR

(node:6076) [DEP_WEBPACK_COMPILATION_CACHE] DeprecationWarning: Compilation.cache was removed in favor of
Compilation.getCache()
(Use `node --trace-deprecation ...` to show where the warning was created)


 ERROR

(node:6076) [DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_HASH] DeprecationWarning: [hash] is now
[fullhash] (also consider using [chunkhash] or [contenthash], see documentation for details)


 ERROR

(node:6076) [DEP_WEBPACK_DEPRECATION_ARRAY_TO_SET_INDEXER] DeprecationWarning: chunk.files was changed from Array to Set (in
dexing Array is deprecated)

Can Anyone solve this?


Solution

  • As the error prompts in:

    See our docs page for more info on this error: https://gatsby.dev/debug-html

    Your issue relies on the fact that gatsby develop occurs in the browser (where there are window and other global objects while gatsby build occurs in the Node server, where for obvious reasons there is no window (summarizing a lot).

    When dealing with own code, you can bypass this issue wrapping your logic in the following condition:

    import * as React from "react"
    
    // Check if window is defined (so if in the browser or in node.js).
    const isBrowser = typeof window !== "undefined"
    
    export default function MyComponent() {
      let loggedIn = false
      if (isBrowser) {
        window.localstorage.getItem("isLoggedIn") === "true"
      }
    
      return <div>Am I logged in? {loggedIn}</div>
    }
    

    Source: https://www.gatsbyjs.com/docs/debugging-html-builds/

    The snippet above will avoid a breaking build because it won't execute the offending part of the code thanks to typeof window !== "undefined" condition.

    However, in your case, you are not dealing with own code so you need to tell webpack to avoid the transpilation of the offending modules. Add the following snippet in your gatsby-node.js:

    exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
      if (stage === "build-html" || stage === "develop-html") {
        actions.setWebpackConfig({
          module: {
            rules: [
              {
                test: /bad-module/,
                use: loaders.null(),
              },
            ],
          },
        })
      }
    }
    

    Basically, you are overwriting webpack's default configuration by telling it to ignore (or to add a null loader) to the /bad-module/ dependency. As you can see, the test rule is a regular expression (that's why is wrapped between slashes) so you will need to change /bad-module/ for the name of the dependency in node_modules. Something like this should work:

    exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
      if (stage === "build-html" || stage === "develop-html") {
        actions.setWebpackConfig({
          module: {
            rules: [
              {
                test: /react-pdf/, // check /pdfjs-dist/ too
                use: loaders.null(),
              },
            ],
          },
        })
      }
    }
    

    react-pdf is trying to use window and/or document, what are undefined global objects at build-time to make their stuff so you are forced to pass a null loader to avoid the code-breaking. This is a "common" practice when dealing with third-party dependencies that use window in Gatsby.

    Since it may not be exactly the third-party dependency that is causing the issue (it may be some dependency of react-pdf) you will need to make some trials testing dependencies based on the output log. Clean the cache in each trial using gatsby clean command.