import/no-duplicates
Disallow importing the same module more than once in a file
fixable
Also called import-x/no-duplicates
Two import lines for one module make it harder to see what a file takes from it, and they're often left over from a merge. One line says it all.
The rule compares the files that the paths resolve to, so ./utils and ./utils.js count as the same module. Each of the imports is reported.
A namespace import (import * as) can't be merged with named imports, so it's allowed next to one. The same goes for import type next to a value import.
--fix merges the imports into the first one.
Configure#
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"import/no-duplicates" = "error" # or "warn"Every option, set to its default:
bunfig.toml
[lint.rules]
"import/no-duplicates" = ["error", {
prefer-inline = false,
considerQueryString = false,
}]Examples#
example.js2 problems
import { readFile } from "node:fs/promises"node:fs/promises imported multiple times.;
import { join } from "node:path";
import { writeFile } from "node:fs/promises"node:fs/promises imported multiple times.;utils.js
export const clamp = (n, min, max) => Math.min(Math.max(n, min), max);
export const sum = items => items.reduce((a, b) => a + b, 0);example.js2 problems
import { clamp } from "./utils"/project/utils.js imported multiple times.;
import { sum } from "./utils.js"/project/utils.js imported multiple times.;example.jsNo problems
import { readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";example.tsNo problems
import * as React from "react";
import { useState } from "react";
import type { ReactNode } from "react";Options#
| Option | Default | What it does |
|---|---|---|
prefer-inline | false | Report import type { A } next to import { b } from the same module. --fix merges them as import { type A, b }. |
considerQueryString | false | Resolve the part of a path before a ? and compare the part after it as text. |
example.tswith
{ "prefer-inline": true }2 problemsimport { useState } from "react"react imported multiple times.;
import type { ReactNode } from "react"react imported multiple times.;example.tswith
{ "prefer-inline": true }No problemsimport { useState, type ReactNode } from "react";With considerQueryString, these two paths are the same module:
logo.js
export const width = 64;
export const height = 64;example.jswith
{ "considerQueryString": true }2 problemsimport { width } from "./logo?inline"/project/logo.js?inline imported multiple times.;
import { height } from "./logo.js?inline"/project/logo.js?inline imported multiple times.;And these two aren't:
example.jswith
{ "considerQueryString": true }No problemsimport logoUrl from "./logo.svg?url";
import logoText from "./logo.svg?raw";