Skip to content

chore(assets): modernise frontend lint tooling (ESLint 10 flat config, Prettier 3, Stylelint 17) - #3775

Open
Vondry wants to merge 8 commits into
bolt:6.1from
Vondry:chore/frontend-lint-tooling
Open

chore(assets): modernise frontend lint tooling (ESLint 10 flat config, Prettier 3, Stylelint 17)#3775
Vondry wants to merge 8 commits into
bolt:6.1from
Vondry:chore/frontend-lint-tooling

Conversation

@Vondry

@Vondry Vondry commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

First of many PRs splitting up the Vue 3 / TypeScript work into reviewable pieces. This one touches tooling only — no framework migration, no TypeScript, no runtime dependency changes.

Changes

  • All changes in source code are only FORMAT CHANGES caused by Prettier update (there was no other manual code change)
  • Modernized dev deps stack (updated libs and drop unused libs)

Since all code changes are format only stuff, thus targeting this as a patch release and not minor (I am assuming that all upcoming PRs regarding this vue3/typescript will be targeted for 6.2 as they will require some touches to the assets code)

Testing

  • I manually tested that all admin pages are working as expected (also cypress is passing both locally and in CI)

@Vondry
Vondry force-pushed the chore/frontend-lint-tooling branch 3 times, most recently from 574382f to d11f1fb Compare August 4, 2026 06:40
Vondry added 7 commits August 4, 2026 10:38
None of these are referenced by the source, the webpack config or CI:

- Jest stack (jest, babel-jest, vue-jest, jest-serializer-vue,
  @vue/test-utils, babel-core bridge) plus the "jest" block in
  package.json and the "test" script. There are no JS unit tests in the
  repo, so this setup has never run.
- The Jest-only "env.test" block in .babelrc. Encore builds with
  NODE_ENV=dev|production, never "test", so this never applied.
- stimulus and @symfony/stimulus-bridge. The webpack config does not
  call enableStimulusBridge().
- vue-router. Nothing imports it.

vue-template-compiler is kept: vue-loader 15 needs it at build time even
though nothing imports it directly.

No runtime dependency is touched and the build config is unchanged.
Removes 435 packages from the install tree.
Replaces .eslintrc.js with eslint.config.mjs and moves the lint tooling
to current majors:

  eslint                  6.8  -> 10.8
  eslint-plugin-vue       6.2  -> 10.10
  eslint-plugin-prettier  3.4  -> 5.5
  eslint-config-prettier  6.15 -> 10.1
  eslint-plugin-cypress   2.15 -> 6.4
  prettier                1.19 -> 3.9

Notes:

- eslint-plugin-vue 10 defaults to the Vue 3 rule set, so the config
  selects "flat/vue2-recommended" explicitly. The codebase stays Vue 2.7.
- babel-eslint is dropped. It was only needed for syntax that ESLint's
  own parser has supported for years.
- eslint-plugin-standard is dropped. It was listed under "plugins" but
  the config never enabled a single standard/* rule.
- The "import/resolver" setting is dropped. eslint-plugin-import was
  never installed, so it resolved nothing.
- printWidth moves from the prettier/prettier rule override into
  .prettierrc so there is one source of truth. The effective value is
  unchanged at 120.
- .prettierrc drops jsxBracketSameLine, which Prettier 3 removed and
  which did nothing here (no JSX). arrowParens is pinned to "avoid" to
  keep Prettier 1's output and hold the reformat down.
- --ext is gone in flat config, so the lint scripts become "eslint
  assets". The set of linted files is unchanged.

The newer rule sets report three findings against existing code. All
three are switched off, scoped to the files that trigger them, so that
this PR changes no runtime logic and new violations elsewhere still
fail:

- vue/no-mutating-props in File.vue, Image.vue and Select.vue, which
  write to their own props. A genuine bug class, but fixing it changes
  behaviour.
- no-useless-assignment in File.vue and Image.vue, a dead folderPath
  initialiser. Safe to remove, but it is still a runtime-code edit.

vue/no-required-prop-with-default is left on as a warning: Date.vue
declares "mode" both required and with a default. Warnings do not fail
the build, so the finding stays visible without forcing a change here.

Formatting is NOT applied here - it lands in the next commit so this one
stays readable. Lint is red between the two.

package-lock.json keeps every pin from master except the lint tooling
and its own transitive dependencies. The old lockfile pinned
eslint-plugin-vue 6 and vue-eslint-parser 7, which npm could not
reconcile with the new peer graph, so those subtrees were dropped and
re-resolved. Nothing else was allowed to drift: all 28 runtime
dependencies resolve to the same versions as on master.
Pure output of "eslint assets --fix". No hand edits.

Prettier 3 differs from 1.19 in two ways that show up here:

- a space before the parens of anonymous functions,
  "function()" -> "function ()"
- member chains collapse onto one line more eagerly, which mostly
  affects the jQuery chains in Collection.vue

arrowParens was pinned to "avoid" in the previous commit specifically to
keep this diff small: 16 files, no reindentation, no semantic change.

Reviewable by re-running the command rather than by reading the diff.
  stylelint                         13.13 -> 17.14
  stylelint-config-standard         19    -> 40
  stylelint-config-recommended-scss 4.3   -> 17
  stylelint-scss                    3.21  -> 7.2

stylelint-config-recommended-scss and stylelint-scss were listed under
"dependencies". They are lint-time only, so they move to
devDependencies and drop out of the runtime install.

The "syntax": "scss" option was removed in Stylelint 14; it becomes
"customSyntax": "postcss-scss".

The newer standard config reports 722 findings against the existing
SCSS. All of them are convention rules that did not exist in Stylelint
13, not bugs, so this commit changes no SCSS and switches them off:

- import-notation is off because it wants @import 'x' rewritten to
  @import url('x'). Sass treats url() imports as plain CSS imports and
  would stop resolving the partials, which breaks the build. Same
  reasoning for no-invalid-position-at-import-rule and the two
  scss/load-* rules, which assume a @use-based codebase.
- The rest (colour notation, alpha notation, operator spacing, ...) are
  formatting preferences. Adopting them means touching every SCSS file
  and rebuilding the CSS, which belongs in its own PR.

selector-class-pattern is kept enabled with a BEM-aware pattern instead
of being switched off. All 52 class names it flagged are already valid
block__element--modifier, so the convention is now enforced rather than
abandoned; camelCase and snake_case selectors still fail.

assets/scss/vendor/ is excluded. Those files style third-party widgets
and have to use their class names (.CodeMirror, .flatpickr-*), which no
project-wide selector convention can accommodate. That accounts for 281
of the 722 findings.
  cypress  15.16.0 -> 15.19.0

Same major, so no API changes. Verified by running the full e2e suite
against both versions locally, in a CI-equivalent environment
(APP_ENV=prod, fresh schema + fixtures, fixture files restored between
runs):

  15.16.0   59 passing, 0 failing
  15.19.0   59 passing, 0 failing

Per-spec test counts are identical, so no spec silently stopped being
collected.

Two changes in this range were worth checking against this repo:

- 15.17.0 made config loading strict: a .js config now follows the
  "type" field in package.json instead of retrying on format mismatch.
  package.json declares no "type", so it defaults to CommonJS and the
  two CommonJS cypress.config.*.js files still load. Note for whoever
  converts webpack.config.js to ESM later: adding "type": "module"
  without renaming those configs to .cjs will break the e2e run.
- 15.18.0 changed scrolling in horizontally-scrollable containers, and
  cypress.config.ci.js sets scrollBehavior: 'nearest'. No spec changed
  behaviour as a result.

Dev-only dependency: it is not bundled and does not affect build output.
@Vondry
Vondry force-pushed the chore/frontend-lint-tooling branch from d11f1fb to 761a267 Compare August 4, 2026 08:38
@Vondry
Vondry force-pushed the chore/frontend-lint-tooling branch from 761a267 to 5e6ea62 Compare August 4, 2026 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant