import/no-commonjs

Disallow require(), module.exports and exports.* in favor of import and export

Also called import-x/no-commonjs

In a project that uses ES modules, a require() or module.exports written out of habit mixes two module systems. Bundlers can't tree-shake anything that's loaded with require(), and the other import/* rules can't check names that are exported through module.exports.

A require() is reported if it has one string as its argument and isn't inside a function. By default it's also allowed inside an if, a try, a ? : or an &&, || or ??, because an import declaration can't be conditional.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"import/no-commonjs" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"import/no-commonjs" = ["error", {
  allowRequire = false,
  allowConditionalRequire = true,
  allowPrimitiveModules = false,
}]

Examples#

example.js2 problems
const { parse } = require("./parse");

module.exports = { run: text => parse(text) };
example.js1 problem
import { parse } from "./parse";

exports.run = text => parse(text);
example.jsNo problems
import { parse } from "./parse";

export const run = text => parse(text);

let colors;
try {
  colors = require("colors");
} catch {}

export function loadMarkdown() {
  return require("markdown-it");
}

Options#

OptionDefaultWhat it does
allowRequirefalseAllow every require(). module.exports and exports.* are still reported.
allowConditionalRequiretruefalse also reports a require() inside an if, a try, a ? : or a logical expression.
allowPrimitiveModulesfalseAllow module.exports = value if the value isn't an object literal.

The string "allow-primitive-modules" instead of the object means { "allowPrimitiveModules": true }.

example.jswith { "allowRequire": true }No problems
const { parse } = require("./parse");

export const run = text => parse(text);
example.jswith { "allowConditionalRequire": false }1 problem
let colors;
try {
  colors = require("colors");
} catch {}

export { colors };

With allowPrimitiveModules, a module may export one function or one string:

example.jswith { "allowPrimitiveModules": true }No problems
module.exports = function run(text) {
  return text.trim();
};
example.jswith { "allowPrimitiveModules": true }1 problem
module.exports = { run };

When not to use it#

Leave it off in a project that's written in CommonJS, and for config files that a tool loads with require().