Skip to content

chore(lint): modernize and unify linting configuration#6004

Open
caseyisonit wants to merge 71 commits intomainfrom
caseyisonit/linting-poc
Open

chore(lint): modernize and unify linting configuration#6004
caseyisonit wants to merge 71 commits intomainfrom
caseyisonit/linting-poc

Conversation

@caseyisonit
Copy link
Contributor

@caseyisonit caseyisonit commented Feb 4, 2026

Description

Modernizes the repository's linting infrastructure by upgrading to ESLint 9 with flat config, centralizing all linting at the root, and adding unified commands for checking and fixing code across the entire codebase.

The RFC is stored temporarily in the style-guide in contributor docs: CONTRIBUTOR-DOCS/02_style-guide/temp_linting-RFC.md. It will be removed before merge and provides the context and reasoning for the changes. Start there for full background. This PR includes minor linting fixes in the Badge component across all systems as examples. A follow-up PR will apply linting to the entire repo (possibly phased in multiple PRs merged in sequence).

Motivation and context

The existing linting setup had several pain points:

  • ESLint was using the legacy .eslintrc format (deprecated in ESLint 9)
  • Linting dependencies were scattered across sub-packages
  • No unified commands for running all linters
  • Inconsistent behavior between local, lint-staged, and CI environments
  • Missing Prettier check in CI

This PR addresses these by consolidating all linting at the root with a single configuration per tool (eslint.config.js, stylelint.config.js, .prettierrc.yaml), so behavior is consistent wherever linting is run.

Related issue(s)

  • Related to ongoing DX improvements for contributor tooling

Summary of changes

ESLint modernization

  • Upgraded to ESLint 9 with flat config (eslint.config.js)
  • Added plugins: eslint-plugin-lit, eslint-plugin-wc, eslint-plugin-jsdoc, eslint-plugin-mdx, eslint-plugin-jsonc, eslint-plugin-notice
  • Centralized all rules at root with targeted overrides for tests, stories, scripts, and legacy patterns (icons/elements, react wrappers)
  • Inlined custom @spectrum-web-components/eslint-plugin rules; header enforced via eslint-plugin-notice with linters/HEADER.js

Stylelint enhancements

  • Root stylelint.config.js (ES module) with stylelint-config-standard, stylelint-order, and custom @spectrum-web-components/stylelint-header-plugin (swc/header) for CSS
  • Property order: Logical, idiomatic order via order/properties-order and linters/stylelint-property-order.js (recess-order style), enforced as errors (not alphabetical)
  • 2nd-gen only: stylelint-declaration-strict-value as warning for design token enforcement
  • 1st-gen: Overrides that relax vendor-prefix and specificity rules for 1st-gen/**/*.css

Unified commands

Command Description
yarn lint Check all (ESLint, Stylelint, Prettier)
yarn format Fix all (ESLint, Stylelint, Prettier)
yarn lint:eslint Check JavaScript/TypeScript only
yarn lint:1st-gen ESLint for 1st-gen only
yarn lint:2nd-gen ESLint for 2nd-gen only
yarn lint:styles Check CSS only
yarn lint:prettier Check formatting only
yarn format:eslint Fix JavaScript/TypeScript only
yarn format:styles Fix CSS only
yarn format:prettier Fix formatting only

Pre-commit and CI

  • lint-staged (lint-staged.config.js): ESLint and Stylelint with --fix, Prettier; lit-analyzer for staged 1st-gen package source; package.json version generation, yarn constraints --fix, lockfile refresh; .changeset/*.md escape script
  • CI: Reviewdog for ESLint and Stylelint on changed files; Prettier check on changed files; all use the same root configs

Documentation

Follow-up work

  • Run yarn format across the repo to fix pre-existing lint errors (separate PR, possibly phased)
  • Document or extend clickEventsAllowList in eslint.config.js for lit-a11y as needed

Author's checklist

  • I have read the CONTRIBUTING and PULL_REQUESTS documents.
  • I have reviewed the Accessibility Practices for this feature, see: Aria Practices
  • I have added automated tests to cover my changes.
  • I have included a well-written changeset if my change needs to be published.
  • I have included updated documentation if my change required it.

Reviewer's checklist

  • Includes a Github Issue with appropriate flag or Jira ticket number without a link
  • Includes thoughtfully written changeset if changes suggested include patch, minor, or major features
  • Automated tests cover all use cases and follow best practices for writing
  • Validated on all supported browsers
  • All VRTs are approved before the author can update Golden Hash

Manual review test cases

  • Verify yarn lint runs ESLint, Stylelint, and Prettier

    1. Run yarn lint from the repo root
    2. Observe that all three tools run and report issues
    3. Expect no crashes or configuration errors
  • Verify yarn format fixes issues across all tools

    1. Run yarn format from the repo root
    2. Observe that fixable issues are corrected
    3. Expect files to be modified with fixes applied
  • Verify lint-staged runs on commit

    1. Stage a .ts or .css file with a fixable issue
    2. Run git commit
    3. Expect lint-staged to fix the issue and include it in the commit
  • Verify CI runs Prettier check

    1. Push a branch with unformatted code
    2. Observe CI lint job
    3. Expect Prettier step to fail and report the issue

Device review

  • Did it pass in Desktop?
  • Did it pass in (emulated) Mobile?
  • Did it pass in (emulated) iPad?

caseyisonit and others added 30 commits November 7, 2025 10:00
- Add ESLint 9.x and related plugins to root package.json
- Remove ESLint dependencies from 1st-gen/package.json
- Remove ESLint dependencies from 2nd-gen/package.json
- Remove ESLint dependencies from example-project-rollup
- All linting dependencies now managed at root level
- Add eslint-plugin-mdx for linting .md and .mdx files
- Remove CONTRIBUTOR-DOCS from ESLint ignore list
- Disable code block linting (docs contain partial code snippets)
- Update research doc with markdown/MDX linting recommendations
- Align css-custom-vars-viewer with root typescript-eslint version
- Add eslint-plugin-lit@2.1.1 with 15 rules for Lit template validation
- Add eslint-plugin-wc@3.0.1 with 9 rules for Web Component correctness
- Add documented browser globals for DOM, events, observers, network APIs
- Remove unused eslint-formatter-pretty dependency
- Pin all ESLint dependencies to exact versions (no carets)
- Update all packages to latest stable versions:
  - @eslint/js: 9.39.2
  - @typescript-eslint/*: 8.54.0
  - eslint: 9.39.2
  - eslint-config-prettier: 10.1.8
  - eslint-plugin-jsonc: 2.21.0
  - eslint-plugin-lit-a11y: 4.1.4
  - eslint-plugin-mdx: 3.6.2
  - eslint-plugin-simple-import-sort: 12.1.1
  - eslint-plugin-storybook: 10.2.1
  - jsonc-eslint-parser: 2.4.2
- Add eslint-plugin-jsdoc@62.5.0 with minimal rule set
- Configure custom tags for Custom Elements Manifest (CEM):
  @element, @slot, @csspart, @cssproperty, @fires, @attr, @Attribute, @internal
- Add additional browser globals for HTML element types:
  HTMLSlotElement, HTMLInputElement, HTMLButtonElement, etc.
- Rules focus on consistency, not requiring docs everywhere:
  - check-alignment (error): Consistent asterisk alignment
  - check-indentation (warn): Consistent description indentation
  - check-param-names (error): Param names match function signature
  - check-tag-names (error): Only valid JSDoc/CEM tags
  - check-types (warn): Prefer lowercase primitives
  - require-param-description (warn): Encourage param descriptions
  - require-returns-description (warn): Encourage return descriptions
  - valid-types (warn): Valid type expressions
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit

stylelint

🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "display" to come before "border-radius"


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "grid-template-columns" to come before "gap"


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "display" to come before "align-items"


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "display" to come before "border-left"


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "padding" to come before "overflow"


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "container-type" to come before "border-radius"


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "display" to come before "container-type"


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "width" to come before "height"


🚫 [stylelint] <selector-pseudo-element-colon-notation> reported by reviewdog 🐶
Expected double colon pseudo-element notation


🚫 [stylelint] <selector-pseudo-element-colon-notation> reported by reviewdog 🐶
Expected double colon pseudo-element notation


🚫 [stylelint] <selector-pseudo-element-colon-notation> reported by reviewdog 🐶
Expected double colon pseudo-element notation

sp-tab-panel:not(.section):focus code-example:after {


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "margin" to come before "font-style"


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "font-family" to come before "color"

font-family: var(--swc-sans-font-family-stack);


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "line-height" to come before "letter-spacing"

line-height: var(--swc-detail-line-height);


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "margin-block-end" to come before "line-height"


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "margin-block-start" to come before "margin-block-end"


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "color" to come before "background-color"

color: var(--swc-neutral-content-color-default, rgb(34 34 34));


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "font-family" to come before "color"

font-family: var(--swc-sans-font-family-stack);


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "margin" to come before "font-style"


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "color" to come before "background-color"

color: var(--swc-neutral-content-color-default);


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "-webkit-tap-highlight-color" to come before "color"

-webkit-tap-highlight-color: rgb(0 0 0 / 0%);


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected an empty line before property "-webkit-tap-highlight-color"

-webkit-tap-highlight-color: rgb(0 0 0 / 0%);


🚫 [stylelint] <order/properties-order> reported by reviewdog 🐶
Expected "font-family" to come before "background-color"

font-family: token("sans-serif-font");

Copy link
Contributor

@5t3ph 5t3ph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two minor suggestions!

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

Labels

High priority PR review PR is a high priority and should be reviewed ASAP Status: Ready for review PR ready for review or re-review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants