Visitar URL original
USWDS - JS: Add ESLint rules that can detect CommonJS/ESM mistakes · Issue #6849 · uswds/uswds · GitHub
Skip to content

USWDS - JS: Add ESLint rules that can detect CommonJS/ESM mistakes #6849

Description

@ethangardner

Summary

eslint.config.mjs currently sets languageOptions.sourceType: "module"
for every file in packages/, and injects Node's require/module
globals for those same files -- so ESLint currently cannot distinguish a
CommonJS file from an ESM file, and cannot catch the most common mistake
that will come up while converting files from one to the other (see the
parent issue #6845 for full context). This issue adds the rules that make that
distinction possible, ahead of any actual source conversion.

The specific mistake this needs to catch

When a CommonJS module does module.exports = { prefix: "usa" }, converting
its importers to import { prefix } from "./config.js" looks correct but
throws at runtime: SyntaxError: Named export 'prefix' not found. The
correct, universally-safe form is
import config from "./config.js"; const { prefix } = config; (default
import, then destructure). This is exactly the class of error eslint-plugin-import-x's
import/named rule is designed to catch.

Scope

Restructure eslint.config.mjs into (at least) these scoped blocks, adding
rules only where they apply:

  • ESM source block (files: ["packages/**/*.js", "packages/**/*.mjs"],
    excluding packages/usa-icon/src/usa-icons.config.js -- see note
    below): add
    - import/named: "error"
    - import/no-cycle: "error" (there are currently zero import cycles
    in packages/ source; this rule keeps it that way, which matters
    because a later part of this migration relies on the dependency
    graph staying acyclic)
    - import/extensions: ["warn", "ignorePackages", { js: "always", mjs: "always" }]
    -- land this as a warning, not an error, since it will fire on
    every extensionless relative require() call currently in the
    codebase (there are many). A shrinking warning count in CI output
    over the course of this migration is a useful progress signal for
    reviewers. It gets flipped to "error" in the final cleanup issue of this migration (USWDS - JS: Migration cleanup -- delete the Storybook CJS-to-ESM transform plugin, tighten lint rules, fix stale docs #6869), once no CommonJS source remains.
    - import/no-commonjs: leave this off in this issue. It gets
    turned on incrementally, one directory at a time, by each later
    conversion issue in this migration, as that directory's files
    glob -- turning it on globally now would just fail on every
    unconverted file and add no signal.
  • Node-tooling block (gulpfile.js, tasks/**/*.js (but not
    tasks/**/*.mjs, which are already ESM), .storybook/**/*.js,
    svgo.config.js, webpack.twig.config.js,
    packages/usa-icon/src/usa-icons.config.js): explicitly set
    languageOptions.sourceType: "commonjs" and keep Node globals. This
    block should have import/no-commonjs explicitly disabled (these
    files are meant to stay CommonJS).
  • Note: packages/usa-icon/src/usa-icons.config.js lives inside
    packages/ but is a Node-side build config
    (tasks/svg-sprite.js does require("../packages/usa-icon/src/usa-icons.config")),
    not browser-facing component source. It must be excluded from the
    "ESM source" block above and included in the "Node-tooling" block, or
    it will be mistakenly targeted by later conversion work.
  • npm run lint:js passes with only the expected import/extensions
    warnings (no new errors).

Verification

npm run lint:js

Confirm the warning count roughly matches the number of extensionless
relative require()/import specifiers currently in packages/ (order of
magnitude: over 100).

Depends on

Should land after "Tooling hygiene ahead of the ESM migration" (#6846; which
widens lint:js's scope to the whole repo -- this issue's Node-tooling
block needs that widened scope to have any effect).

Activity

  1. added
    Help wantedCommunity contributions are welcome; scope and acceptance criteria should be clear before applying.
    javascriptPull requests that update javascript code
    ModernizationModernizing project code, tooling, or dependencies
    on Aug 27, 2026
  2. added theissue type on Sep 16, 2026
  3. added
    Affects: BuildRelates to the build process
    and removed
    javascriptPull requests that update javascript code
    on Sep 17, 2026
  4. ravitejapioneerblaze-code commented on Sep 19, 2026

    @ravitejapioneerblaze-code
    Contributor

    Hi team, I'd like to work on this issue and will submit a PR as outlined. Please let me know if it's already being handled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Affects: BuildRelates to the build processContext: JavaScriptIssue is in JavaScriptHelp wantedCommunity contributions are welcome; scope and acceptance criteria should be clear before applying.ModernizationModernizing project code, tooling, or dependencies

    Type

    Projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions