Skip to content

Fix compatible plugin chaining when prettier-vscode passes plugin.name as an absolute path on Windows.#459

Open
ramong26 wants to merge 1 commit into
tailwindlabs:mainfrom
ramong26:fix/windows-plugin-name-normalization
Open

Fix compatible plugin chaining when prettier-vscode passes plugin.name as an absolute path on Windows.#459
ramong26 wants to merge 1 commit into
tailwindlabs:mainfrom
ramong26:fix/windows-plugin-name-normalization

Conversation

@ramong26
Copy link
Copy Markdown

@ramong26 ramong26 commented May 16, 2026

What

Resolved a plugin chaining compatibility issue between:

  • @ianvs/prettier-plugin-sort-imports
  • prettier-plugin-tailwindcss

The issue started occurring on prettier-plugin-tailwindcss >= 0.7.3.

Problem

In a Windows + pnpm + prettier-vscode environment, the following symptoms were observed:

  • Depending on plugin order, only one feature worked:

    • import sorting
    • Tailwind class sorting
  • VSCode format-on-save and CLI formatting produced different results

  • prettier-plugin-tailwindcss@0.7.2 worked correctly, while 0.7.3+ introduced the issue

Related issues:

Root Cause

prettier-plugin-tailwindcss internally checks enabled plugins using plugin names.

However, in prettier-vscode on Windows, plugin names are resolved as native file paths:

D:\...\@ianvs\prettier-plugin-sort-imports\...

while compatibility checks expect slash-based package names:

@ianvs/prettier-plugin-sort-imports

Because Windows paths use backslashes (\), plugin chaining silently failed.

Fix

Normalized plugin names before passing them into the parser chain.

parser.preprocess = async (code: string, options: ParserOptions) => {
  const compatibleNames = opts.compatible ?? []

  const normalizePluginName = (pluginName: string) => {
    const slashed = pluginName.replace(/\\/g, '/')

    return (
      compatibleNames.find((compatibleName) =>
        slashed.includes(compatibleName),
      ) ?? pluginName
    )
  }

  const patchedOptions = {
    ...options,
    plugins: options.plugins.map((plugin) => {
      if (typeof plugin === 'string') {
        return plugin
      }

      if (plugin instanceof URL) {
        return plugin
      }

      if (!plugin.name) {
        return plugin
      }

      return {
        ...plugin,
        name: normalizePluginName(plugin.name),
      }
    }),
  }

  const parser = await load(patchedOptions)

  return parser.preprocess
    ? parser.preprocess(code, patchedOptions)
    : code
}

Result

Both features now work correctly together:

  • import sorting
  • Tailwind class sorting

Verified in:

  • Windows 11
  • pnpm workspace
  • prettier-vscode
  • CLI (prettier --write)

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