Skip to content

fix(migrate): remove scoped Prettier plugins and shareable configs - #2557

Open
m0g3r wants to merge 1 commit into
voidzero-dev:mainfrom
m0g3r:fix/prettier-scoped-plugin-cleanup
Open

fix(migrate): remove scoped Prettier plugins and shareable configs#2557
m0g3r wants to merge 1 commit into
voidzero-dev:mainfrom
m0g3r:fix/prettier-scoped-plugin-cleanup

Conversation

@m0g3r

@m0g3r m0g3r commented Aug 25, 2026

Copy link
Copy Markdown

Problem

vp migrate removes Prettier itself, but a migrated project keeps installing dead Prettier
packages under most naming shapes. rewritePrettierPackageJson matched only the exact name
prettier and the flat prettier-plugin-* prefix, so all of these survived migration:

  • scoped plugins — @trivago/prettier-plugin-sort-imports, @ianvs/prettier-plugin-sort-imports,
    @shopify/prettier-plugin-liquid
  • the official @prettier/ scope — @prettier/plugin-php, @prettier/plugin-xml,
    @prettier/plugin-ruby
  • shareable configs — prettier-config-*, @scope/prettier-config
  • @types/prettier

The asymmetry looks arbitrary rather than intentional: unscoped prettier-plugin-sort-imports is
removed, while the scoped package of the same name is not.

The sibling ESLint path already gets this right. isEslintEcosystemDep in
migrator/eslint.ts recognises named packages, flat prefixes, whole scopes, the scoped
^@[^/]+\/eslint-(plugin|config|formatter)(-.+)?$ form, and treats @types/NAME symmetrically
with NAME.

Changes

Adds isPrettierEcosystemDep mirroring isEslintEcosystemDep, and routes both dependency loops
through it.

The matched set is deliberately narrow, and a test pins that: eslint-config-prettier,
eslint-plugin-prettier, prettierx, and an unrelated @prettierx/ scope are all preserved.

Also deliberately unchanged:

  • the fields scanned. peerDependencies and optionalDependencies are still left alone. The
    ESLint path does scrub them, but whether migration should silently drop a declared peer
    dependency is exactly what a P1 on feat(migrate): preserve dynamic Oxlint and Oxfmt configs #2483 is currently about, so I have not imported that decision
    here.
  • empty containers. The ESLint path deletes a dependency field it empties; this one still
    leaves "devDependencies": {}. Same reasoning — separate concern, separate PR if wanted.

rewritePrettierPackageJson becomes exported. migrator/README.md rule 1 asks for module functions
to be exported so the barrel surfaces them, and it makes the function unit-testable exactly like
rewriteEslintPackageJson.

Testing

Six cases added to migrator.spec.ts, next to the rewriteEslintPackageJson block and following
its conventions.

Verified in both directions: with the old matcher restored and the new tests kept, 4 fail;
with the fix, 6/6 pass. The two that pass either way are the guards for behaviour that is meant
to be unchanged (unrelated-name preservation, and the no-op case).

Checks actually run:

  • migrator.spec.ts — before/after diffed in the same build state: identical failure set both
    ways (139)
    , with the change adding exactly 6 passing tests (206 → 212).
  • oxlint@1.79.0 (the repo's pin) with -D correctness -D perf -D suspicious on both changed
    files — no new findings. The one reported error is pre-existing and byte-identical on the
    unmodified files, and is a rule this repo sets to off in vite.config.ts.
  • oxfmt@0.64.0 (the repo's pin), configured from this repo's fmt block — clean, and clean on
    untouched control files too.
  • git diff --check — clean.

Not run: vp check, pnpm test:unit, tsgo, and the PTY snapshot suite, which need a full
workspace build my environment cannot produce. No PTY fixture covers rewritePrettierPackageJson,
and this change adds no CLI output.

AI assistance

Claude Opus 5 wrote the implementation, the tests, and this description. The change is
agent-authored and has not had a separate human review. Every result quoted above is from an actual
run, not an estimate.

`rewritePrettierPackageJson` matched only the exact name `prettier` and the
flat `prettier-plugin-*` prefix, so a migrated project kept installing dead
Prettier packages under any other naming shape — scoped plugins such as
`@trivago/prettier-plugin-sort-imports`, `@ianvs/prettier-plugin-sort-imports`
and `@shopify/prettier-plugin-liquid`, everything in the official `@prettier/`
scope (`plugin-php`, `plugin-xml`, `plugin-ruby`), shareable configs, and
`@types/prettier`.

The asymmetry was arbitrary rather than deliberate: the sibling ESLint path
already recognises all of these shapes via `isEslintEcosystemDep`, including
the scoped `^@[^/]+\/eslint-(plugin|config|formatter)(-.+)?$` form.

Add `isPrettierEcosystemDep` mirroring that helper, and route both dependency
loops through it. The matched set stays deliberately narrow: names that merely
contain "prettier" (`eslint-config-prettier`, `prettierx`, an unrelated
`@prettierx/` scope) are preserved. The dependency fields scanned are unchanged
— `peerDependencies` and `optionalDependencies` are still left alone.

`rewritePrettierPackageJson` becomes exported, per `migrator/README.md`'s rule
that module functions are exported so the barrel surfaces them, which also lets
it be unit-tested like its ESLint counterpart.
@netlify

netlify Bot commented Aug 25, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview ready!

Name Link
🔨 Latest commit 539ec1a
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a8d52d41a9223000897c5ac
😎 Deploy Preview https://deploy-preview-2557--viteplus-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@fengmk2

fengmk2 commented Aug 25, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 539ec1aa2f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// Scopes whose every package is part of the Prettier ecosystem.
// @prettier/* — official Prettier scope (@prettier/plugin-php,
// @prettier/plugin-xml, @prettier/plugin-ruby, @prettier/sync)
const PRETTIER_ECOSYSTEM_SCOPES = ['@prettier/'];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve non-plugin packages in the @prettier scope

When a project imports @prettier/sync programmatically and its Prettier peer remains available transitively or through automatic peer installation, matching the entire @prettier/ scope now deletes the package even though this migration only converts configuration and CLI scripts—it does not rewrite source imports. The subsequent install therefore makes that import fail. Restrict scope-wide cleanup to actual plugin packages, or check source usage before deleting non-plugin APIs such as @prettier/sync.

Useful? React with 👍 / 👎.

Comment on lines +225 to +226
// Flat name prefixes that mark a Prettier-only package.
const PRETTIER_ECOSYSTEM_PREFIXES = ['prettier-plugin-', 'prettier-config-'];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Update the migration contract for the expanded cleanup

This expands destructive manifest rewriting to prettier-config-*, scoped plugin/config packages, and the entire @prettier/* scope, but the documented migration contract was not updated: rfcs/migration-command.md step 4 still promises removal only of prettier and unscoped prettier-plugin-*, while the canonical docs/guide/migrate-rules.md does not describe these additional removals. Update the migration documentation so users reviewing generated manifest changes can predict the new cleanup.

AGENTS.md reference: AGENTS.md:L66-L67

Useful? React with 👍 / 👎.

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.

2 participants