Skip to content

feat: content mapper (v4 alpha) - #6170

Draft
johnsoncodehk wants to merge 17 commits into
masterfrom
feat/vue-content-mapper
Draft

feat: content mapper (v4 alpha)#6170
johnsoncodehk wants to merge 17 commits into
masterfrom
feat/vue-content-mapper

Conversation

@johnsoncodehk

@johnsoncodehk johnsoncodehk commented Aug 20, 2026

Copy link
Copy Markdown
Member

Summary

Draft prototype of the TypeScript content mapper integration for Vue, as the foundation for v4. This is an alpha-stage experiment, not ready for merge.

Direction for v4

  • v4 targets content mapper as the only type-checking path.
  • vue-tsc is removed (packages/tsc) — no transition shim, no Vue-specific type-check CLI.
  • Users type-check with native TypeScript: tsc --runExternalCode, with contentMappers declared in tsconfig.
  • Vue ships a @vue/typescript-content-mapper package.

Dependency strategy

  • typescript is pinned to <7 (full classic API) and overridden to typescript-native-bridge (tnb) — this keeps tsc -b and tsslint working on TS 6.
  • typescript-7 (alias to typescript@7.1.0-dev) is reserved for content-mapper tests.
  • vue-component-meta: typescript moved from an optional peer to a direct <7 dependency.

What's in this branch

  • New packages/content-mapper package implementing the JSON-RPC content-mapper protocol (initialize / openProject / transform / closeProject) over @vue/language-core:
    • protocol.ts, server.ts, project.ts
    • spanMappings.ts — Volar mappings → SpanMapping
    • diagnosticDirectives.ts@vue-expect-error support
    • worker.ts / workerPool.ts — parallel transforms via worker threads
  • extensions/vscode/src/extension.tsregisterContentMappers activation
  • packages/language-core — codegen changes for diagnostic directives / ignore regions
  • vue-tsc removed

Status / progress

Legend: [x] done · [~] partial · [ ] todo

Foundation

  • vue-tsc removed
  • content-mapper protocol implemented (initialize / openProject / transform / closeProject)
  • span mapping + diagnostic directives + worker pool
  • unit tests pass (spanMappings, diagnosticDirectives, project, workerPool, localization)
  • integration tests pass against a locally built tsgo (build, dts, fixtures, corpus)
  • CI clones + builds tsgo and runs the content-mapper tests

Diagnostic model

  • unmapped / synthesized-region diagnostics: Volar discards them; content mapper reports them (CLI shows the transformed snippet, LSP collects them at the top of the file, declared-but-not-used is auto-suppressed) → eliminated at the codegen source in fix(language-core): eliminate unmapped codegen diagnostics #6179
  • code-level diagnostic filtering (verification.shouldReport2339 / 2551 / 2353 / 2561 / 6133): the protocol has no per-code filtering
  • [~] @vue-expect-error / @vue-ignorediagnosticDirectives (mapper-side partial)
  • scaffolding type-checks and parses cleanly (currently does not; POC synthesizes ignore regions)

Mapping structure

Feature model

  • dynamic feature decisions (shouldReport / shouldHighlight / shouldRename / resolveRename*) → static SpanMapFeature
  • rename text rewrite (resolveRenameNewName / resolveRenameEditText) + Verbatim-only edits
  • Vue-specific completion markers (__importCompletion / __propsCompletion / __shorthandExpression)
  • fine-grained completion flags (completion.isAdditional / completion.onlyImport)

Config & emit

  • [~] config surface: vueCompilerOptionsoptions / dynamicConfig + configIdentity / watchedFiles (target:auto, plugins)
  • [~] declaration emit: App.d.vue.ts naming, no JS emit, no declaration maps
  • [~] position encoding: UTF-16 end-to-end (assumed, not fully verified)

Testing

  • Run content-mapper tests with a locally built tsgo:

    TSGO_PATH=/path/to/tsgo pnpm test content-mapper
  • tsgo is built in CI from microsoft/typescript-go.

Known blocker

npm typescript@7.1.0-dev.20260819.1 does not yet expose --runExternalCode (TypeScript PR #4712 is approved but not merged/published). CI therefore builds tsgo from source. Integration tests require a tsgo binary with --runExternalCode.

References

@johnsoncodehk johnsoncodehk changed the title feat: content mapper prototype (WIP) feat: content mapper (v4 alpha) Aug 20, 2026
@escaton

escaton commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Just in case, I tested the tsgo + content-mapper in my private project (29367 lines of vue) last weekend before it was merged.

andrewbranch@76d07d9 + andrewbranch/typescript-go@d07c1ff

I found just two inconsistencies in content-mapper version vs vue-tsc@3.3.9 + typescript@6.0.3:

  • v-html is not recognized. Both vue-tsc (ts6 and tnb) do not report that.
test.vue:8:10 - error TS2339: Property 'vHtml' does not exist on type 'GlobalDirectives'.

8     <div v-html="'foo'" />
           ~~~~~~

And that seems a correct error, there is indeed no vHtml in https://github.com/vuejs/core/blob/a2b40db9a83b36ed9da3a16403cf8f040262d73f/packages/runtime-dom/src/index.ts#L62 but somehow vue-tsc makes it any.

  • errors on two style blocks with same module attrubute. This is a good catch that current vue-tsc does not report.
<!-- test.vue -->
<style module="foo" critical>
.foo {
}
</style>
<style module="foo" critical>
.foo {
}
</style>
test.vue:73:16 - error TS2300: Duplicate identifier 'foo'.

73 <style module="foo" critical>
                  ~

Hope that helps

@escaton

escaton commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Btw typescript@next haven't yet been released after content-mappers merge. Today was skipped, probably due to typescript-go repo migration.

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.

3 participants