Remove Eslint Warnings For Dynamic Imports

import/no-dynamic-require & global-require

In JavaScript applications, such as Node and React JS, you might see or use code that requires static files dynamically. As a result, ESlint throws two warnings unless you mute them. The warnings are:

  1. Calls to require() should use string literals eslint(import/no-dynamic-require). That is, a static, unchanged string instead of a dynamic one should be used.

  2. Unexpected require() eslint(global-require). Means, the require statement should be at the top of the file.

Let’s observe why do we need such code, and, in order to remove the ESlint warnings, how can we properly deal with them.

The Reason For Dynamic Requires

More often than not, it comes down to a requirement where you need to require a static file such as png or json dynamically, based on some function argument within the code (such as, coming from API response). Below is the example:

React JS Country Code And Flag Example

Say we want to show the country or language of the user along with its flag in their profile, the countryCode of which is coming from the API. All we need to do is to require that particular png file at runtime. Here’s an example component:

const UserCountry = ({user}) => (
  <div>
    <img src={require(`src/assets/flags/${user.countryCode}.png`).default}> {user.country}
  </div>
)

This is a lazy solution, as it saves plenty of code lines (about 200 countries equals at least these many lines for requiring them separately). But it’s still wrong and to fix the error we need to import all the files separately and statically.

The Solution

  • Create a separate helper file somewhere in the codebase.
  • Require all the static files at the top into const variables or import them. (You can’t require/import them directly in object/hash because it would still not be global require at the top. And of course, you can’t use loop! As it will again be dynamic and not string literal).
  • Create an object/hash and assign all the variables to the key names.
  • Export this object.
  • Import this object in the relevant file(s) and replace the dynamic require code with the one accessing object with dynamic keys.

Example:

// flags.js file

import AD from "../assets/flags/AD.png"; // the path to your png files
import AE from "../assets/flags/AE.png";
import AF from "../assets/flags/AF.png";
// ... other flags
import ZM from "../assets/flags/ZM.png";


// OR in Common JS

const AD = require("../assets/flags/AD.png").default; 
const AE = require("../assets/flags/AE.png").default;
const AF = require("../assets/flags/AF.png").default;
// ... 
const ZM = require("../assets/flags/ZM.png").default;

const flags = {
  AD,
  AE,
  AF,
  //...
  ZM
};

export default flags;

Now in the original code:

import flags from "./flags"; // the path to flags.js

const UserCountry = ({user}) => (
  <div>
    <img src={flags[user.countryCode]} /> {user.country}
  </div>
)

See also