Skip to content

typescript@7 breaks config loading: expressive-code-twoslash is imported eagerly even when twoSlash is disabled #155

Description

@daveycodez

Summary

With typescript@7 installed in the workspace, loading any SolidBase config crashes before Vite even starts — including for projects that never enable twoslash.

failed to load config from .../apps/docs/vite.config.ts
error during build:
TypeError: Cannot read properties of undefined (reading 'ES2022')
    at node_modules/expressive-code-twoslash/dist/index.js:1628:27

Root cause

dist/config/mdx.js imports the twoslash plugin at module top level:

import ecTwoSlash from "expressive-code-twoslash";

but only uses it inside the if (sbConfig.markdown?.expressiveCode?.twoSlash) branch. expressive-code-twoslash evaluates the TypeScript compiler API at module scope (ts.ScriptTarget.ES2022), and it declares typescript as a peer dependency (^5.7), so it resolves whatever TypeScript the host project provides. TypeScript 7 (the native/Go compiler) no longer ships the in-process compiler JS API — the npm package's main export is essentially a version stub — so the import itself throws.

SolidBase's own import { convertCompilerOptionsFromJson } from "typescript" is unaffected because typescript ^5.9.3 is a real dependency of SolidBase and resolves its own copy; it's also only used inside the same twoslash branch.

Suggested fix

Load the plugin lazily, only when the feature is enabled, e.g.:

if (sbConfig.markdown?.expressiveCode?.twoSlash) {
  const { default: ecTwoSlash } = await import("expressive-code-twoslash");
  ...
}

(and move the convertCompilerOptionsFromJson import in with it). Twoslash itself can't support TS 7 until an in-process API exists for the native compiler (twoslash@0.3.x caps its peer range at ^6), so gating the import is the only way for TS 7 projects to use SolidBase — with twoslash off — today.

Environment

  • @kobalte/solidbase 0.6.9
  • typescript 7.0.2
  • @solidjs/start 2.0.0-beta.0, vite 8.1.5
  • bun 1.3.2 (reproduces under both hoisted and isolated linkers whenever expressive-code-twoslash's peer resolution lands on typescript@7)

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