Skip to content

rs fmt: parser-wrapping Prettier plugins are silently ignored under the default Yuku parser #422

Description

@fi3ework

Background

Found while migrating the fmt/lint toolchain of storybook-rsbuild to rstack-cli.

Version

  • rstack 0.6.5 (Node 22.22.3, macOS)
  • prettier-plugin-organize-imports 4.3.0, typescript 5.9.3

Minimal reproduction

Three files in a temp directory, no repository needed:

npm i rstack@0.6.5 prettier-plugin-organize-imports typescript@5
// rstack.config.ts
import { define } from 'rstack'
define.fmt({ plugins: ['prettier-plugin-organize-imports'] })
// a.ts — imports intentionally unsorted
import { z } from './z'
import { a } from './a'
console.log(a, z)
npx rstack fmt --no-cache a.ts

What is expected?

Per the "Prettier plugins" section of the formatting guide, the plugin takes effect and the imports get sorted (a before z).

What is actually happening?

Output is No changes needed and the file is untouched — the plugin never runs, with no error or warning of any kind.

Supporting evidence (pointing at parser routing): append to the config

overrides: [{ files: '*.{ts,tsx,mts,cts}', options: { parser: 'typescript' } }]

and the same command sorts the imports correctly.

Analysis

Plugins like organize-imports work by wrapping Prettier's babel/typescript parsers (they declare a parsers object on their export). rs fmt handles JS/TS with the Yuku parser by default, so Prettier's parser pipeline is bypassed and the plugin is never invoked — silently.

Suggested fix

A seamless fallback, zero user configuration: when the worker loads a plugin, inspect its exported parsers object; if the plugin overrides a parser that Yuku would otherwise replace (typescript, babel, …), automatically route the affected languages through the Prettier parser path. With that in place, the docs only need one behavioral note: languages covered by such a plugin use the Prettier parser, with different performance characteristics than Yuku.

Side note: typescript version interference

Pin typescript@5 when reproducing. The plugin sorts via TypeScript's Language Service API (a peer dependency); typescript@7.0.2 (the native Go port) ships no JS API (ts.createLanguageService is undefined), and the plugin's internal catch silently returns the original code — so it appears to not sort even with the parser override. That is a plugin × TS7 compatibility problem, independent of the Yuku routing issue here, but the two overlap in symptoms and can confuse reproduction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions