fix(cli): support TypeScript 7 when loading capacitor.config.ts#8534
Open
conbrad wants to merge 1 commit into
Open
fix(cli): support TypeScript 7 when loading capacitor.config.ts#8534conbrad wants to merge 1 commit into
conbrad wants to merge 1 commit into
Conversation
TypeScript 7 dropped the classic compiler API (transpileModule, ModuleKind, etc.) from its default export, so requireTS's use of ts.transpileModule throws on projects with typescript@7 installed and every command that reads capacitor.config.ts fails immediately. Detect when that API isn't available and fall back to Node's own built-in TypeScript syntax stripping via a real dynamic import (stable since Node 23.6, available behind --experimental-strip-types since Node 22.6) instead of transpiling the file ourselves. Falls back to a clear error if neither is available. Projects on older TypeScript versions are unaffected: the existing transpileModule path is unchanged. Fixes ionic-team#8531
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TypeScript 7 dropped the classic compiler API (
transpileModule,ModuleKind, etc.) from its default export, sorequireTS's use ofts.transpileModulethrows on projects withtypescript@7installed and every command that readscapacitor.config.tsfails immediately.This change detects when that API isn't available and falls back to Node's own built-in TypeScript syntax stripping via a real dynamic
import()(stable since Node 23.6, available behind--experimental-strip-typessince Node 22.6) instead of transpiling the file ourselves. Falls back to a clear error if neither is available. Projects on older TypeScript versions are unaffected: the existingtranspileModulepath is unchanged.Fixes #8531
Description
Change Type
Rationale / Problems Fixed
TypeScript 7 dropped the classic compiler API (
transpileModule,ModuleKind, etc.) from its default export:require('typescript')now only exposesversion/versionMajorMinor, with the replacement living behind non-call-compatibletypescript/unstable/*subpaths.requireTSincli/src/util/node.tscallsts.transpileModule(...)withmodule: ts.ModuleKind.CommonJSto transpilecapacitor.config.tson the fly, so on any project withtypescript@7installed, every command that loads the config (sync,run,copy,config, etc.) fails immediately withTypeError: Cannot read properties of undefined (reading 'CommonJS').This PR detects when the classic compiler API isn't available and falls back to loading the config via a real dynamic
import(), letting Node's own built-in TypeScript type-stripping do the work instead (stable since Node 23.6, available behind--experimental-strip-typessince 22.6, Capacitor CLI already requires Node >=22). Projects on TypeScript <7 are unaffected; the existingtranspileModulepath is unchanged.Fixes #8531
Tests or Reproductions
Verified against the minimal repro project linked in #8531 (bradenbiz/cap-ts7-repro), which pins
typescript@7.0.2and@capacitor/cli@8.3.3.npx cap configreproduces the exact failure from the issue before this fix, and correctly resolves the config (appId: 'com.example.repro',appName: 'repro',webDir: 'dist') after it.Also verified in the same project:
typescript@6(the repro's own control case) and confirmed the pre-existingtranspileModulepath is untouched and still resolves the config correctly.npm run build(tsc),npm run lint(eslint + prettier), and the full CLI Jest suite (npm test, 44 tests) all pass.Screenshots / Media
N/A
Platforms Affected
Notes / Comments
await import()gets downleveled to a plainrequire()call bytscwhen compiling to CommonJS (the CLI's build target), which silently defeats this fix sincerequire()doesn't invoke Node's ESM loader/type-stripping. Worked around by constructing the import vianew Function('specifier', 'return import(specifier)'), a standard idiom for preserving genuine dynamicimport()semantics through a CJS-targetedtscbuild. Flagging it explicitly here since it looks unusual on first read of the diff.