bun/no-eager-dynamic-import

Disallow import() that runs as soon as the module is loaded

The point of import() is to load a module only when it's needed. An import() at the top level of a file runs as soon as the file is imported, so the module is always loaded. With await, everything that imports the file waits for it too. Move the call into the function that needs the module, or write an import statement.

Configure#

Off by default. To turn it on:

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

Examples#

example.js1 problem
const { marked } = await import("marked");

export function render(text) {
  return marked.parse(text);
}
example.jsNo problems
export async function render(text) {
  const { marked } = await import("marked");
  return marked.parse(text);
}
example.jsNo problems
import { marked } from "marked";

export function render(text) {
  return marked.parse(text);
}

A function that's called right where it's defined, a static field, and a static block also run while the file loads:

example.js3 problems
(async () => {
  const { marked } = await import("marked");
  console.log(marked.parse(text));
})();

class Renderer {
  static parser = import("marked");
  static {
    import("./plugins.js");
  }
}

The import() that tells Vitest which module to mock is allowed in vi.mock(), vi.doMock(), vi.unmock(), and vi.doUnmock():

example.jsNo problems
import { vi } from "vitest";

vi.mock(import("./database.js"), () => ({ connect: vi.fn() }));

When not to use it#

In an ES module, a top-level import() is how you choose a module at run time, as in await import(isBun ? "./bun.js" : "./node.js"). Disable the rule on that line.