Skip to content

feat(content-mapper): add experimental content mapper for TypeScript 7 - #442

Draft
mizdra wants to merge 8 commits into
mainfrom
content-mapper
Draft

feat(content-mapper): add experimental content mapper for TypeScript 7#442
mizdra wants to merge 8 commits into
mainfrom
content-mapper

Conversation

@mizdra

@mizdra mizdra commented Aug 11, 2026

Copy link
Copy Markdown
Owner

ref: #377

Summary

The primary purpose of this PR is to prototype content mappers in a real-world tool and to give feedback to the TypeScript team, who are asking ecosystem tooling authors for input on the proposal (microsoft/typescript-go#2824).

TypeScript 7 (typescript-go) does not support TypeScript Server Plugins, so css-modules-kit cannot provide its language features through the current mechanism. This PR adds @css-modules-kit/content-mapper, an experimental package implementing the proposed alternative: content mappers (microsoft/typescript-go#4712, unmerged).

A content mapper transforms CSS Modules files into typed TypeScript code and hands it to tsgo. In editors, this enables language features such as Go to Definition, Find All References, Rename, and completion. In the plain tsc CLI, imports of CSS Modules type-check without any generated .d.ts files.

What's included

  • server: communicates with tsgo over JSON-RPC on stdin/stdout
  • transformer: parses CSS Modules and generates typed TypeScript code with span mappings. Checks such as whether an imported token exists are delegated to TypeScript's own diagnostics through real imports in the generated code
  • Non-module .css files are transformed into an empty module (export {}), so side-effect imports type-check
  • e2e tests: the ts-plugin e2e tests are ported and run over LSP against a real tsgo binary built from a pinned commit
  • An example for manual verification (examples/7-content-mapper) and a launch configuration tsgo (7-content-mapper)

Intentionally not implemented

Some ts-plugin features are left out on purpose because the content mapper design makes them unnecessary:

  • cmkOptions.enabled: registering the mapper in the tsconfig contentMappers field is itself the opt-in, so a separate option to disable the plugin is unnecessary
  • Excluding generated .d.ts files from module resolution: the content mapper provides types directly from the transformed code without generating .d.ts files, so there are no generated files to exclude
  • css-modules-kit's own diagnostics for unresolved specifiers and non-existent imported tokens: as described above, these are delegated to TypeScript's own diagnostics (TS2307 / TS2339)

Known limitations

  • Some ts-plugin features cannot be implemented even though we would like to: completion customization (e.g. prioritizing the paired CSS module in auto-import suggestions, the className attribute snippet), code fixes (e.g. adding a missing CSS rule), and the "Create CSS Module file" refactor. A content mapper can only transform file contents and has no way to customize language service responses; these features would require the middleware mechanism discussed separately in API usage patterns for complex editor extensions microsoft/typescript-go#2824
  • 44 tests are intentionally left failing due to limitations on the tsgo side (e.g. Find All References and Rename miss occurrences when a token is imported from another CSS file via @import or @value ... from), so the CI test job will be red

How to verify

  • Run vp test --project e2e (the first run clones and builds tsgo, which takes a few minutes)
  • VS Code: launch tsgo (7-content-mapper) from Run and Debug and try the language features in examples/7-content-mapper
  • CLI: in examples/7-content-mapper, run ../../.tmp/typescript-go/built/tsgo -p tsconfig.json --loadExternalPlugins

🤖 Generated with Claude Code

@mizdra mizdra added the Type: Feature New Feature label Aug 11, 2026
@changeset-bot

changeset-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 0781f25

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@css-modules-kit/core Minor
@css-modules-kit/ts-plugin Minor
@css-modules-kit/codegen Minor
@css-modules-kit/eslint-plugin Minor
@css-modules-kit/stylelint-plugin Minor
css-modules-kit-vscode Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Feature New Feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant