fix(lint): let prettier have the last word after eslint --fix - #744
Merged
Conversation
Closes #739. Running the repo's own lint fixer produced a file the repo's own format check rejected, so fixing lint the documented way landed a red `Frontend Check (format)`. It is not a rule disagreement, and eslint-config-prettier cannot prevent it. That package only turns rules OFF, and the culprit is not a formatting rule: `import-extensions/ban-inline-type-imports` rewrites an import, and its AUTOFIXER emits its own text — import type {Page} from '@playwright/test'; — which is not what prettier wants (`{ Page }`, no semicolon). Any autofixer that constructs source can do this; disabling formatting rules does not stop it. So `lint-fix` now re-runs the formatter afterwards, which makes the two tools ordered instead of competing: eslint decides what the code SAYS, prettier decides how it LOOKS, in that order, always. That matches the config's own stated doctrine — "exactly one of them is allowed an opinion and prettier is it". Verified both directions on a clean tree: `eslint --fix` alone leaves prettier --check REJECTING, and the chained script leaves it passing. WORTH KNOWING, and the reason this went unnoticed: the two tools do not cover the same files. lint -> eslint src (src only) format -> prettier "**/*.{js,ts,vue,css,scss}" (everything, incl. tests/) `tests/e2e/**` is format-checked but never linted, so an eslint --fix run there is outside the workflow CI exercises — which is exactly where I hit this. Whether to widen eslint's scope to tests/ is a real decision with a findings backlog behind it, so it stays in #739 rather than riding along here.
Contributor
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 720/720 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-24 22:52 UTC
Download the full PDF report from the workflow artifacts.
rubenvdlinde
added a commit
to ConductionNL/filinq
that referenced
this pull request
Aug 25, 2026
Same fix as ConductionNL/stackiq#744; this repo has the identical shape. `lint-fix` ran eslint's fixer and stopped, so any autofixer that CONSTRUCTS source could leave the tree failing `format`. `eslint-config-prettier` cannot prevent that — it only turns rules off, and the offenders are not formatting rules: `import-extensions/ban-inline-type-imports` and friends rewrite an import and emit their own text, which prettier then rejects. Chaining the formatter afterwards makes the two tools ordered rather than competing: eslint decides what the code SAYS, prettier decides how it LOOKS, in that order, always. THE REASON THIS KEEPS BITING, and it is structural rather than anyone's mistake: lint -> eslint src (src ONLY) format -> prettier "**/*.{js,ts,vue,css,scss}" (everything, incl. tests/) A new file under `tests/e2e/**` is format-checked in CI but NEVER linted, and nothing local tells you before you push. Measured today on filinq#796, where a new Playwright spec went red on `Frontend Check (format)` alone while all 42 other checks passed. Whether to widen eslint's scope to `tests/` is a separate decision with a findings backlog behind it, and is not settled here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #739.
Running the repo's own lint fixer produced a file the repo's own format check
rejected — so fixing lint the documented way landed a red
Frontend Check (format).It is not a rule disagreement
eslint-config-prettieris already applied last ineslint.config.mjs, and itcannot prevent this. That package only turns rules off, and the culprit is
not a formatting rule.
import-extensions/ban-inline-type-importsrewrites an import, and itsautofixer emits its own text:
Any autofixer that constructs source can do this. Disabling formatting rules
does not stop it, because the rule doing the damage is not one of them.
The fix
lint-fixnow re-runs the formatter afterwards:That makes the two tools ordered rather than competing: eslint decides what
the code says, prettier decides how it looks, in that order, always. It is
also what the config's own doctrine already says — "exactly one of them is
allowed an opinion and prettier is it".
Verified both directions on a clean tree:
Why this went unnoticed — worth knowing
The two tools do not cover the same files:
linteslint src— src onlyformatprettier "**/*.{js,ts,vue,css,scss}"— everything, includingtests/tests/e2e/**is format-checked but never linted, so aneslint --fixrunthere is outside the workflow CI exercises — which is exactly where I hit this.
Whether to widen eslint's scope to
tests/is a genuine decision with a findingsbacklog behind it, so it stays in #739 rather than riding along in a one-line
script fix.