Skip to content

build: upgrade to TypeScript 7 - #54172

Merged
MarshallOfSound merged 1 commit into
claude/spec-native-esmfrom
claude/typescript-7
Sep 21, 2026
Merged

MarshallOfSound merged 1 commit into
claude/spec-native-esmfrom
claude/typescript-7

Conversation

@MarshallOfSound

Copy link
Copy Markdown
Member

Description of Change

Before: TypeScript 5.8, with build/bundle/typecheck.mjs driving the compiler API to type check lib/.

After: TypeScript 7.0, the native compiler, which ships no JavaScript API. With script/ and spec/ already on Node's type stripping, what is left is the swap itself: typecheck.mjs spawns tsc (and tsconfig.electron.json sets rootDir to the parent checkout instead of filtering the rootDir diagnostics after the fact), tsconfig.json drops the removed baseUrl option, tsconfig.default_app.json moves off the removed node module resolution, declare module NodeJS becomes a namespace, and a few lib/, spec and docs snippets wrap Buffers for the stricter typings Blob now expects.

Checklist

Release Notes

Notes: none


Generated by Claude Code

@socket-security

socket-security Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedtypescript@​5.8.3 ⏵ 7.0.29910089 -1100100 +10

View full report

@MarshallOfSound
MarshallOfSound added this pull request to stack #54173 September 21, 2026 09:13
@MarshallOfSound
MarshallOfSound requested a review from a team as a code owner September 21, 2026 09:36
stack merge was automatically disabled September 21, 2026 19:59

Pull Request is not mergeable

stack merge was automatically disabled September 21, 2026 20:04

Pull Request is not mergeable

TypeScript 7.0 is the native compiler and ships no JavaScript API. The
earlier changes in this series already moved everything that transpiled
on the fly (script/ and spec/) onto Node's own type stripping, so what
is left here is the compiler swap itself:

* typescript ^5.8.3 -> ^7.0.2.
* build/bundle/typecheck.mjs spawns tsc instead of driving the compiler
  API (the rootDir/private-field diagnostics it used to filter out are
  handled by tsconfig.electron.json setting rootDir to the parent
  checkout instead).
* tsconfig.json drops the removed baseUrl option and anchors the paths
  mapping explicitly; tsconfig.default_app.json moves off the removed
  "node" module resolution; `declare module NodeJS` becomes a namespace.
* A few lib/, spec and docs snippets wrap Buffers for the stricter
  Buffer/ArrayBuffer typings that Blob now expects.

Copy link
Copy Markdown
Member Author

linux-x64 / test / test (linux, 3) and linux-x64 / test-wayland / test (linux, 1) failed on f632c3b in the "Download Src Artifacts" step with Failed to ListArtifacts: (403) Forbidden: Error from intermediary from the Actions artifact service (around 20:43 UTC; the asan build on #54170 hit the same error at the same minute), before any tests ran. Not related to this change; I'll re-run the failed jobs once the rest of the run finishes.


Generated by Claude Code

@MarshallOfSound
MarshallOfSound merged commit 8a6429e into main Sep 21, 2026
117 of 121 checks passed
@MarshallOfSound
MarshallOfSound deleted the claude/typescript-7 branch September 21, 2026 22:21
@release-clerk

release-clerk Bot commented Sep 21, 2026

Copy link
Copy Markdown

No Release Notes

@trop

trop Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

@MarshallOfSound has manually backported this PR to "45-x-y", please check out #54193

MarshallOfSound added a commit that referenced this pull request Sep 22, 2026
…ript 7 (45-x-y) (#54193)

* test: assert that import and require expose the same electron module (#54166)

The `electron` module that ES module code sees is produced by wrapping the
CommonJS one, so both should expose exactly the same names bound to
exactly the same objects. Nothing checked that until now; esm-spec only
verified that the imports do not throw.

A new fixture app loads `electron` (and the process-specific
`electron/main`, `/common`, `/renderer`, `/utility` aliases) through both
`import()` and `require()` in the main process, a utility process and a
non-sandboxed renderer preload, and reports any export that only one
side has, any export that is not the identical value on both sides, and
a default import that is not the `require()` exports object. esm-spec
asserts the report is empty for each process type.

* build: update yarn to 4.18.0 (#54167)

* build: update yarn from 4.12.0 to 4.18.0

Bumps the vendored yarn release (and the DEPS hook, .yarnrc.yml,
script/yarn.js and packageManager references to it) to 4.18.0.
.yarn/releases/yarn-4.18.0.cjs is bin/yarn.js from @yarnpkg/cli-dist@4.18.0
unmodified. The lockfile only changes its metadata version.

Among other fixes, 4.18's built-in TypeScript compatibility patch knows
about the TypeScript 7 package layout; 4.12 fails the fetch step with
ENOENT on lib/_tsc.js when asked to install typescript@7.

* build: bump the nan test lockfile to yarn 4.18's metadata version

The nan spec runner installs nan's test dependencies with the vendored
yarn in immutable mode, and yarn 4.18 refuses the install because it
wants to rewrite the lockfile's metadata version from 8 to 10. Regenerate
the lockfile in the nan patch with 4.18 so the install is a no-op again.

* build: remove release orchestration scripts superseded by Sudowoodo (#52735)

* build: remove release orchestration scripts superseded by Sudowoodo

Follow-up to #52100. Sudowoodo now reads the expected-asset manifest from
script/release/release-assets.json (#52730, electron/sudowoodo#459)
instead of parsing release.ts, which removes the last reason to keep the
dead orchestration code:

- release.ts: no entrypoints since #52100; only remaining consumer was
  Sudowoodo's manifest regex, now retired
- get-url-hash.ts: imported only by release.ts
- upload-node-checksums.py / upload-index-json.py: invoked only by
  release.ts's uploadNodeShasums/uploadIndexJson; Sudowoodo does both
  first-party (checksums-scratchpad merge, direct index.json blob upload)
- get-asset.ts: no importers anywhere

The CI upload subtree stays: upload.py, upload-symbols.py,
upload-node-headers.py, upload-to-github.ts, find-github-release.ts,
github-token.ts, types.ts are invoked by build CI during publish builds
and are unrelated to the Sudowoodo migration.

* build: drop upload.py's unused --publish-release flag

Parsed but never read, and no workflow passes it — a fossil of the
pre-Sudowoodo flow where CI could trigger the publish itself.

* build: run the TypeScript scripts under script/ with plain node (#54168)

ts-node was used as a CLI for a handful of TypeScript scripts under
script/. Those now rely on the type stripping built into Node.js instead:

- script/gen-filenames, check-patch-diff, run-clang-tidy and the release
  helpers (find-github-release, upload-to-github, github-token, types)
  are renamed to .mts and invoked with `node`. They use
  import.meta.dirname and explicit .mts / .js specifiers, and
  tsconfig.script.json moves to nodenext with verbatimModuleSyntax so
  tsc checks them the way Node runs them.
- The documented minimum Node.js for building goes from 22.12 to 22.18,
  the first 22.x release with type stripping on by default.
- script/codesign/gen-trust.ts and its trust.xml template are deleted;
  nothing has invoked them since generate-identity.sh switched to a
  user-scoped keychain in #50058.
- oxfmt, oxlint, lint-staged and .gitattributes learn about .mts.

ts-node itself stays for now because the spec runner still loads specs
through its require hook.

* build: remove the ts-node dependency (#54169)

The last user of ts-node was the spec runner, which registered it as a
require hook so spec/**/*.ts could be loaded inside Electron (the
utility-process net fixture did the same).

Both now register a small local hook, spec/ts-register.js, that
transpiles each .ts file on its own with the TypeScript compiler API
using tsconfig.spec.json and inlines a source map so stack traces still
point at the .ts lines. ts-node also type checked specs as it loaded
them; that check now runs once in the lint job via
`tsc -p tsconfig.spec.json` instead, so type errors in specs fail lint
rather than surfacing part-way through a test shard.

Drops ts-node 6.2.0 and its transitive arrify, buffer-from, diff@3,
make-error, mkdirp@0.5, source-map-support and yn entries from
yarn.lock.

* test: keep spec sources to erasable syntax and explicit type imports (#54170)

Turn on erasableSyntaxOnly and isolatedModules for the spec typecheck so
the specs only use TypeScript syntax that a plain type stripper can
remove (no enums, parameter properties, import = require or angle
bracket casts), and lint spec/ for type-only imports so they are
written as `import type` / inline `type` specifiers.

Also hoist a handful of inline require() calls in spec bodies up to the
existing top-level imports and use named imports from ws.

* test: load specs as native ES modules (#54171)

* test: mechanically rewrite spec imports and __dirname for native ESM

This is the automated half of loading spec/ as native ES modules and is
not expected to pass on its own; the hand-written half follows in the
next commit. A script (included in the pull request description) made
three changes to spec/*.ts and spec/lib/*.ts, then oxfmt was re-run:

* relative import specifiers gain their real file extension
* __dirname / __filename become import.meta.dirname / .filename
* files that still call require() from module code get a
  createRequire(import.meta.url) prelude

Code inside functions that are stringified and evaluated in another
process (remotely(), itremote(), template-interpolated functions and
similar) is left as it was.

* test: load specs as native ES modules with Node's type stripping

spec/package.json declares "type": "module", so the spec runner and every
spec file now load through Node's own ESM loader and built-in TypeScript
type stripping; the require.extensions transpile hook is gone. A new
spec/fixtures/package.json keeps fixtures in a CommonJS scope.

The hand-written changes on top of the mechanical rewrite:

* spec/index.js becomes an ES module and import()s its test dependencies
  after the app is ready, then uses mocha.loadFilesAsync().
* Functions that are stringified and sent to another process now arrive
  as written rather than as CommonJS transpiler output, so the
  remote-control and utility-process fixtures define the plain names
  those bodies use (chai, expect, once, setTimeout, ...) instead of the
  old `electron_1` style shims, and a few bodies require() what they use.
* The two specs that exercise lib/ sources require() them, since lib/ is
  not in a "type": "module" scope.
* spec-helpers resolves BrowserWindow lazily so it stays loadable from a
  utility process.
* tsconfig.spec.json allows .ts extension imports; spec/tsconfig.json
  points editors at it.

* build: upgrade to TypeScript 7 (#54172)

TypeScript 7.0 is the native compiler and ships no JavaScript API. The
earlier changes in this series already moved everything that transpiled
on the fly (script/ and spec/) onto Node's own type stripping, so what
is left here is the compiler swap itself:

* typescript ^5.8.3 -> ^7.0.2.
* build/bundle/typecheck.mjs spawns tsc instead of driving the compiler
  API (the rootDir/private-field diagnostics it used to filter out are
  handled by tsconfig.electron.json setting rootDir to the parent
  checkout instead).
* tsconfig.json drops the removed baseUrl option and anchors the paths
  mapping explicitly; tsconfig.default_app.json moves off the removed
  "node" module resolution; `declare module NodeJS` becomes a namespace.
* A few lib/, spec and docs snippets wrap Buffers for the stricter
  Buffer/ArrayBuffer typings that Blob now expects.
@trop trop Bot added merged/45-x-y PR was merged to the "45-x-y" branch. and removed in-flight/45-x-y labels Sep 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged/45-x-y PR was merged to the "45-x-y" branch. no-backport semver/none

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants