react-pdf: react-scripts: 2.0.3 breaks dependencies in lib/display/api.js and build/pdf.js v3.0.5

Updating create-react-app to v2.0.3 has resulted in this node module to not load PDFs.

Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/pdfjs-dist/lib/display/api.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/pdfjs-dist/lib/display/api.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/pdfjs-dist/lib/display/api.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/pdfjs-dist/build/pdf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/pdfjs-dist/build/pdf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/pdfjs-dist/lib/display/api.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/pdfjs-dist/build/pdf.js

Describe solutions you’ve tried

Deleting the module and reinstalling via npm install has resulted in the same issue.

Additional information

If applicable, add screenshots (preferably with browser console open) and files you have an issue with to help explain your problem.

Environment

  • Browser (if applicable) [e.g. Chrome 57, Firefox 59]: N/A
  • React-PDF version [e.g. 3.0.4]: 3.0.5
  • React version [e.g. 16.3.0]: 16.4.1
  • Webpack version (if applicable) [e.g. 4.16.2]: 4.19.1
  • React scripts: 2.0.3

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 57
  • Comments: 81 (13 by maintainers)

Commits related to this issue

Most upvoted comments

Good news everyone. This issue seem to have been fixed in https://github.com/mozilla/pdf.js/commit/d370037618211c8642dd3c576edbc2d2b3d6e09e! This means that as soon as the next stable release of pdf.js is out, we’ll be able to resolve this issue.

Hi! Any updates?

I still get this error message.

./node_modules/pdfjs-dist/build/pdf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

Environment

  • Browser (if applicable) [e.g. Chrome 57, Firefox 59]: N/A
  • React-PDF version [e.g. 3.0.4]: 3.0.5 and also 4.0.2
  • React version [e.g. 16.3.0]: 16.8.0
  • React scripts: 2.1.3

React-PDF 5.0.0-beta.4 is out with pdf.js 2.4.456 under the hood. Feedback from those previously affected by this bug is welcome 😃

Compiled with warnings.

./node_modules/pdfjs-dist/build/pdf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/pdfjs-dist/build/pdf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/pdfjs-dist/build/pdf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/pdfjs-dist/build/pdf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

Environment

  • React-PDF: 4.0.5
  • React: 16.8.6
  • Webpack: 4.29.6
  • React scripts: 3.0.0
  • Other: pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

Removing the following code block from build/pdf.js suppresses the warnings, still keeping functionality in my case (I’m using external worker):

{
  var useRequireEnsure = false;

  if (typeof window === 'undefined') {
    isWorkerDisabled = true;

    if (typeof require.ensure === 'undefined') {
      require.ensure = require('node-ensure');
    }

    useRequireEnsure = true;
  } else if (typeof require !== 'undefined' && typeof require.ensure === 'function') {
    useRequireEnsure = true;
  }

  if (typeof requirejs !== 'undefined' && requirejs.toUrl) {
    fallbackWorkerSrc = requirejs.toUrl('pdfjs-dist/build/pdf.worker.js');
  }

  var dynamicLoaderSupported = typeof requirejs !== 'undefined' && requirejs.load;
  fakeWorkerFilesLoader = useRequireEnsure ? function () {
    return new Promise(function (resolve, reject) {
      require.ensure([], function () {
        try {
          var worker;
          worker = require('./pdf.worker.js');
          resolve(worker.WorkerMessageHandler);
        } catch (ex) {
          reject(ex);
        }
      }, reject, 'pdfjsWorker');
    });
  } : dynamicLoaderSupported ? function () {
    return new Promise(function (resolve, reject) {
      requirejs(['pdfjs-dist/build/pdf.worker'], function (worker) {
        try {
          resolve(worker.WorkerMessageHandler);
        } catch (ex) {
          reject(ex);
        }
      }, reject);
    });
  } : null;

  if (!fallbackWorkerSrc && (typeof document === "undefined" ? "undefined" : _typeof(document)) === 'object' && 'currentScript' in document) {
    var pdfjsFilePath = document.currentScript && document.currentScript.src;

    if (pdfjsFilePath) {
      fallbackWorkerSrc = pdfjsFilePath.replace(/(\.(?:min\.)?js)(\?.*)?$/i, '.worker$1$2');
    }
  }
}

This warning seems to be related to Mozilla’s PDF.js using require.ensure for fallback purposes, but create-react-app’s webpack configuration warning about it since it’s a non-standard language feature. I’m not sure what the correct solution is, but I’ve opened an issue on the create-react-app repo for discussion, and this issue on the PDF.js repo might also be relevant.

@adnux If you are upgrading, then your old implementation will not work. You will need to follow the Browserify & Others documentation.

Your imports/setup will probably look something like this…

import { pdfjs, Document, Page } from 'react-pdf';

pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

Correct. I’ll be working with Mozilla to getting that fixed once for good, but it will take some time.

@varunpatro I am using craco to allow modification of CRA webpack config, and I remove the { parser: { requireEnsure: false } } rule. My issue was that the CI server would treat the warning as an error and I wasn’t able to deploy the project. Remember it’s a hacky temporary fix 😄

Here is craco.config.js code I use, maybe it will help someone.

const { isEqual } = require("lodash");

module.exports = {
  webpack: {
    configure(webpackConfig) {
      const updatedRules = webpackConfig.module.rules.filter(
        rule => !isEqual(rule, { parser: { requireEnsure: false } })
      );
      webpackConfig.module.rules = updatedRules;

      return webpackConfig;
    }
  }
};

Is this still being worked on or no? @wojtekmaj

Hello, the same issue react-scripts@2.1.8 pdfjs-dist@2.1.266 react-pdf@4.0.5

any updates?

I can confirm, with 5.0.0-beta.4 the error message is gone for me

I’m using the following postinstall script to handle this issue:

#!/usr/bin/env bash
# https://github.com/wojtekmaj/react-pdf/issues/280

set -eu

NL=$(grep -n 'var useRequireEnsure = false' ./node_modules/pdfjs-dist/build/pdf.js | awk -F: '{print $1}')
START=$((NL - 1))
END=$((START + 51))

sed -i.bak -e $START's/{/\/*{/' ./node_modules/pdfjs-dist/build/pdf.js
sed -i.bak -e $END's/}/}*\//' ./node_modules/pdfjs-dist/build/pdf.js

It there any chance to resolve this error at 4.x version? I cannot use 5.x because of compatibility with IE11 😕

Using config-overrides.js with react-app-rewired to override create-react-app webpack configs without ejecting:

In react-scripts v3.1.1 requireEnsure rule is at position 0, you can change it directly.

module.exports = function override(config) {
  config.module.rules[0].parser.requireEnsure = true
  return config
}

Hello, the same issue react-scripts@2.1.5 pdfjs-dist@2.1.266 react-pdf@4.1.0

any news?

Same CI issue as @maciejmatu - I will look into his hack but the person who fixes this properly will have my undying gratitude.

Sure thing, can be done - 5.0 will be out soon so we could advance the beta channel 😃

Is there any temporary fix to this problem at present?

@tzieleniewski @wojtekmaj small automation: add "postinstall": "cp node_modules/pdfjs-dist/build/pdf.worker.min.js public/pdf.worker.min.js" to the scripts section in the package.json

yes.it’s incompatile with react-script-2

error is gone with 5-beta.4

I tried installing 5.0, still getting warnings.

I’m pretty sure nothing has changed quite yet; if I’m interpreting what @wojtekmaj said earlier correctly, my guess is he’ll release version 5.0 – which will ship with pdf.js 2.3.200 – as stable, and then create a new beta version – like 5.1.0-beta.1 – which will ship with pdf.js 2.4.456 (per #550).

@dkrefta We’re using @maciejmatu solution with React-app-rewired and so far didn’t have any issue with it. If that’s helps…

If not for the performance degradation it’d be already live. I don’t think there will be any developer facing changes at this point though.

Pinging this in hopes that this issue might be fixed soon? Any updates? @wojtekmaj

@varunpatro I am using craco to allow modification of CRA webpack config, and I remove the { parser: { requireEnsure: false } } rule. My issue was that the CI server would treat the warning as an error and I wasn’t able to deploy the project. Remember it’s a hacky temporary fix 😄

Here is craco.config.js code I use, maybe it will help someone.

const { isEqual } = require("lodash");

module.exports = {
  webpack: {
    configure(webpackConfig) {
      const updatedRules = webpackConfig.module.rules.filter(
        rule => !isEqual(rule, { parser: { requireEnsure: false } })
      );
      webpackConfig.module.rules = updatedRules;

      return webpackConfig;
    }
  }
};

thanks, it works!!!

If you want to fix this via react-app-rewired and without a CI=false command, insert the following code into config-overrides.js:

const { isEqual } = require("lodash");

module.exports = function override(config, env) {
  // Ensures react-pdf doesn't throw a warning
  const updatedRules = config.module.rules.filter(
    rule => !isEqual(rule, { parser: { requireEnsure: false } })
  );
  config.module.rules = updatedRules;

  // Ensure jest configuration works
  config.collectCoverageFrom = [
    "src/components/**/*.{ts,tsx}",
    "!src/*.{ts, tsx}"
  ];
  return config;
};

This has worked for us without an issue now.

There’s no way. The first version pdfjs shipped with this issue was actually the one that already dropped IE11 support, which we noticed later.

The react-pdf 4.1.0 doesn’t work with pdf.js 2.4.456. 😢

Unless I am reading this wrong, this other react project using pdf-js has resolved this issue: https://github.com/mikecousins/react-pdf-js/releases/tag/v5.1.0 “Moving to the es6 bundled version of pdfjs-dist (@bundled-es-modules/pdfjs-dist) to get rid of the warnings when using Create React App.” Could the same thing be used here?

@llamamoray using react-app-rewired. config-overrides.js file is to override create-react-app webpack configs without ejecting.

I edited my comment to be more complete.

Using config-overrides.js :

In react-scripts v3.1.1 requireEnsure rule is at position 0, you can change it directly.

module.exports = function override(config) {
  config.module.rules[0].parser.requireEnsure = true
  return config
}

@hugonasciutti is this a standard feature in CRA or is this using react-app-rewired?

I am also having this issue, it is getting rather frustrating.

I tried to use /* eslint-disable */ at the top of the build/pdf.js file but that got completely ignored.

I tried removing the code block that @jguitard mentioned, but that didn’t change anything either.

I even tried removing the pdfjs-dist folder altogether, but somehow the project continues to work, and gives the same warnings, referencing files that don’t even exist!

I don’t know what kind of black magic is going on behind the scenes. But I am using an external worker: I have pdf.worker.min.js in my public folder. And I’m using this snippet:

import { Document, Page, pdfjs } from 'react-pdf'
pdfjs.GlobalWorkerOptions.workerSrc = 'pdf.worker.min.js';

Any suggestions would be appreciated.

We caved, asked around at other teams and went with https://github.com/timarney/react-app-rewired instead, also working with pretty much the same workaround that @maciejmatu provided. Also would still like to have an actual solution, but to be fair, that seems to lie more with Mozilla then with @wojtekmaj… So it will probably take forever.

Also disabling the CI flag is absolute nono for us.

As I said there’s absolutely no way 4.x will have this issue fixed. Either upgrade to 5.x or live with it. Sorry.

@PedroRuiz just to confirm, you deleted the npm_modules folder? Before install again the packages?

Hey guys, any updates on this problem? I managed to use the library following the tip from @mikemclin:

import {pdfjs, Document, Page} from 'react-pdf';

pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

But I still get the warning:

./node_modules/pdfjs-dist/build/pdf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

Any current solution without using react-app-rewired?

@wojtekmaj How would you feel about pushing a new beta release with the new pdfjs-dist version so that we can do some testing on our end? i.e. v5.0.0-beta.3?

@bugzpodder Unfortunately pdfjs-dist 2.4.456 is a pre-release and we won’t be updating to unstable dependency. I’m looking forward to Mozilla releasing a stable version, hopefully soon.

If you want to fix this via react-app-rewired and without a CI=false command, insert the following code into config-overrides.js:

const { isEqual } = require("lodash");

module.exports = function override(config, env) {
  // Ensures react-pdf doesn't throw a warning
  const updatedRules = config.module.rules.filter(
    rule => !isEqual(rule, { parser: { requireEnsure: false } })
  );
  config.module.rules = updatedRules;

  // Ensure jest configuration works
  config.collectCoverageFrom = [
    "src/components/**/*.{ts,tsx}",
    "!src/*.{ts, tsx}"
  ];
  return config;
};

This has worked for us without an issue now.

This worked for me, but removed this section:

   config.collectCoverageFrom = [
     "src/components/**/*.{ts,tsx}",
     "!src/*.{ts, tsx}"
   ];

Thanks!

@taddj here is the thing, I spent a lot of hrs to understand what is going on as understanding docs it, not my thing… after looking into the function ‘config-overrides’ you need to assign ‘self’ to the output… here the code basically.

Most of the guys forget to say about this little magic line ‘config.output.globalObject = ‘this’’

  1. look on the repo of https://github.com/timarney/react-app-rewired to understand how to install it, create the file and where to put the file

  2. Past the code and comment 👍

module.exports = function override(config, env) {
  config.output.globalObject = 'this'
  config.module.rules[0].parser.requireEnsure = true

  return config;
};

```