chore: upgrade TypeScript to 5.9.3 and enable .ts imports#3043
chore: upgrade TypeScript to 5.9.3 and enable .ts imports#3043bennypowers wants to merge 39 commits into
Conversation
|
Add explicit `type` annotations to all type-only imports and exports. This is a pure TypeScript syntax change with no runtime effect -- the compiled JavaScript output is identical. It prepares for Node 24's type stripping, which requires `import type` for type-only imports since they are erased at runtime. 93 files changed across dev-server, test-runner, rollup-plugin, and storybook packages. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Upgrade TypeScript from 5.0.4 to 5.9.3 - Update eslint, prettier, and related dev dependencies - Enable `module: nodenext` and `rewriteRelativeImportExtensions` in tsconfigs - Rewrite all relative imports from .js to .ts extensions - Add `type` keyword to type-only imports across source files - Remove TypeScript parameter properties from constructors (DevServer, PluginSyntaxError, WebSocketsManager) - Fix internal-ip CJS interop for nodenext module resolution - Add @ts-ignore for deprecated puppeteer accessibility API Zero runtime behavior change — output remains CJS. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
prettier-plugin-package v1.x requires prettier ^2, which conflicts with our upgrade to prettier ^3.7.1. v2.0.0 supports prettier ^3. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@typescript-eslint v8 enables stricter rules by default. Disable rules that flag pre-existing code patterns: - no-require-imports: CJS require() in .js files - no-unused-expressions: chai expect() assertions in tests - no-empty-object-type: {} type usage - no-unsafe-function-type: Function type usage - no-unused-vars: allow unused catch parameters Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TS 5.9 with module:nodenext requires explicit return type annotation when the inferred type references a non-portable path (TS2742). Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…Extensions TypeScript's rewriteRelativeImportExtensions injects a __rewriteRelativeImportExtension helper into the output. This helper is not needed in browser bundles and breaks test execution. Add stripRewriteImportExtensionPlugin to remove the helper from the rollup output. Also add resolveMochaPlugin for robust monorepo module resolution. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Test files were accidentally copied from fix/node24 which included test migration changes (node:test, import.meta). Those belong in PR2. Restored to master versions with only .ts import extension rewrites. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Restore dev-server-rollup test files to master versions: the sed import rewrite incorrectly changed assertion strings like "import moduleA from './module-a-stub.js'" to use .ts extensions. Only actual import statements should use .ts extensions. - Add hanbi.d.ts ambient declarations for packages that use hanbi in tests (dev-server-core, dev-server-hmr, dev-server-import-maps, test-runner-core). With module:nodenext, untyped CJS modules need explicit declarations. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove leaked PR4 files: JSDoc→TS conversions (.ts files in config-loader, parse5-utils, rollup-plugin-copy, rollup-plugin-import-meta-assets, storybook-utils) belong in PR4, not PR1 - Override JSDoc package tsconfigs to use module:commonjs/moduleResolution:node since their .js source files are incompatible with nodenext - Fix parse5 Token→Attribute type import for parse5 v6 compat - Fix Object.values(bundle) unknown type with explicit cast - Add CJS interop for saucelabs and internal-ip (build errors with nodenext) - Add CJS interop for rollup plugins in storybook-builder - Restore master test scripts (test migration belongs in PR2) - Remove tsx devDep from test-runner-core (belongs in PR2) - Add workaround for @jridgewell/remapping .d.cts TS 5.9 syntax error - Restore rollup-plugin-html source files from master with .ts imports Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
With module:nodenext, ts-node fails on untyped CJS modules (like hanbi). Override moduleResolution to 'node' for test execution via mocha+ts-node. This is temporary — PR2 migrates all tests to node:test which doesn't need ts-node. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ts-node with module:nodenext treats .ts files as ESM, causing "Cannot require() ES Module" errors. Override both module and moduleResolution to commonjs/node for test execution. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
koa v3 + @types/koa v3 and ws v8 + @types/ws v8 are required for module:nodenext compatibility. @types/koa v2 and ws v7 types don't resolve correctly with nodenext module resolution. Add build script workaround to remove nested @types/koa and @types/ws installed by transitive dependencies (@rocket/cli) which conflict with the workspace package versions. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Restore parse5 to ^6.0.1 in all packages (v8 migration is in PR4) - Keep koa v3 / ws v8 in dev-server-core (required for nodenext compat) - Use WebSocketServer from ws v8 API - Remove nested @types cleanup for ws (not needed) Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The dist/index.js path was from PR4's JSDoc→TS conversion. On PR1, parse5-utils is still a JSDoc package with main: src/index.js. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use TS_NODE_TRANSPILE_ONLY=true for mocha tests (skip type checking) - Fix Console read-only property in DynamicTerminal - Fix parse5 v6 type issues in hashInlineScripts with any casts - Fix playwright devtools option with @ts-ignore - Fix rollup-plugin-external-globals CJS export= import - Disable strict/checkJs in JSDoc package tsconfigs - Regenerate package-lock.json from clean install Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Restore ALL test files to master versions - Restore parse5-utils JSDoc .js source - Fix Token → Attribute imports for parse5 v6 - Use --loader ts-node/esm for mocha tests - Restore dev-server integration test to master Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
With module:nodenext, --require ts-node/register fails with "Unknown file extension .ts". Switch to --loader ts-node/esm with TS_NODE_TRANSPILE_ONLY=true to skip type checking. Also restore dev-server integration test and parse5-utils test script to master versions. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ts-node with module:nodenext fails to handle .ts files. Override to module:commonjs + moduleResolution:node + rewriteRelativeImportExtensions:false via TS_NODE_COMPILER_OPTIONS for test execution through mocha. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
….json Add ts-node section to tsconfig.node-base.json to override module to commonjs for test execution. This allows mocha + ts-node/register to work with the nodenext base config. Restore all test scripts to exact master versions (no TS_NODE_ prefixes). Regenerate package-lock.json from scratch to fix parse5 v8 leak. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add ts-node.compilerOptions to all package tsconfigs (module:commonjs, moduleResolution:node, rewriteRelativeImportExtensions:false) - Fix parse5-utils tsconfig with allowJs/checkJs/emitDeclarationOnly - Restore parse5 v6 types in source files (Token -> Attribute) - Fix extractModulesAndAssets missing extractAssets param - Fix hashInlineScripts parse5 type casts - Restore parse5-utils .js source - Regenerate package-lock.json Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ts-node/register with module:nodenext fails on Node 18-22. Set TS_NODE_COMPILER_OPTIONS to override module to commonjs, moduleResolution to node, and rewriteRelativeImportExtensions to false for test execution only. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ts-node/register fails on Node 18-22 when the tsconfig has module:nodenext because Node doesn't support .ts file extensions. Setting TS_NODE_SKIP_PROJECT=true prevents ts-node from reading the tsconfig entirely, and TS_NODE_COMPILER_OPTIONS provides minimal commonjs config for test compilation. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
mocha + ts-node/register is incompatible with module:nodenext on Node 18-22 (.ts file extension not recognized). Update all CI workflows to use Node 24 which natively supports TypeScript. Remove TS_NODE_ env var overrides from test scripts since they're no longer needed on Node 24. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Test files import from source using .js extensions which don't resolve on Node 24 with module:nodenext. Apply the same .js -> .ts import rewrite to test files as was done for source files. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Node 24 native TS requires explicit `import type` for type-only imports. Copy all source .ts files from fix/node24 which have the correct type keywords. Restore parse5 v6 types for files with DefaultTreeAdapterTypes. Fix package subpath imports (.ts -> .js for @web/* package imports). Fix extractModulesAndAssets type mismatch. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Copy browser-logs source from fix/node24 for correct `import type` - Add ./test-helpers.js to dev-server-core exports map for nodenext - Remove erroneous .js from bare package specifiers (@web/foo.js -> @web/foo) Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Re-apply .ts import rewrites to test files after they were lost in a previous git checkout operation. Also fix bare package specifiers that had erroneous .ts extension. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PR1 emits CJS output (no "type": "module" yet), so import.meta is not available. Revert to __dirname in browserScript.ts and createServer.ts. Remove __esModule export from RollupPluginHTMLOptions. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Restore ALL test files to master versions with only .ts import rewrites (removes leaked node:test/node:assert imports from PR2) - Replace @typescript-eslint/ban-types with no-empty-object-type in inline disable comments (ban-types removed in v8) - Fix invalid typeof comparison in rollupAdapter.ts - Add eslintConfig.root: true to prevent parent config interference - Add react-dom devDependency for storybook builder tests - Regenerate package-lock.json from master base Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allow unused function arguments prefixed with underscore. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The previous sed only matched lines starting with import/export, missing multi-line imports where 'from' is on a continuation line. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
prettier v3 no longer has bin-prettier.js. Use npx prettier instead. Format files that were changed but not auto-formatted. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix missing .ts extensions and mangled imports from rebase onto node24/import-type base branch. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d7b44b2 to
ebfbe33
Compare
Node 18 and 20 are EOL. Bump engines to >=22.0.0 across all packages. CI matrix now tests 22, 24, and latest (26). Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
33a92c0 to
5f48b6c
Compare
web-padawan
left a comment
There was a problem hiding this comment.
Please consider splitting this PR further if you'd like to proceed to make reviewing easier.
| @@ -1,4 +1,4 @@ | |||
| import { Middleware } from 'koa'; | |||
| import type { Middleware } from 'koa'; | |||
There was a problem hiding this comment.
note: there are still quite a few import type changes in this PR like this one. Consider extracting them into separate PR now when #3052 is merged.
| "is-stream": "^2.0.0", | ||
| "isbinaryfile": "^5.0.0", | ||
| "koa": "^2.16.1", | ||
| "koa": "^3.1.1", |
There was a problem hiding this comment.
suggestion: extract koa upgrade into separate PR to keep this one about TS upgrade.
| "@mdn/browser-compat-data": "^4.0.0", | ||
| "@web/dev-server-core": "^0.7.4", | ||
| "esbuild": "^0.27.0", | ||
| "esbuild": "^0.25.0", |
There was a problem hiding this comment.
note: this change should be reverted, let's not downgrade esbuild.
There was a problem hiding this comment.
as discussed in chat, i think ts 5.9.3 was premature. i'd rather go for node:test first, then when 22 reaches eol, update minimum node to 24, and only then tackle typescript
playwright is the joker. we might need to deprecate a11ySnapshot
|
Closing: maintainers agreed to ship EOL deprecation and node:test migration before TS upgrade. Keeping branch for reference. |
Summary
Upgrade to TS 5.9.3 with
module: nodenext,rewriteRelativeImportExtensions, and.js->.tsimports. CJS interop wrappers added for ESM-incompatible packages.Drop EOL Node versions: all packages now require
>=22.0.0. Node 18 and 20 are past EOL. CI matrix tests on 22, 24, and latest.This is a non-breaking internal change. Published output remains CJS.
Stack
import typeannotations.tsimports, drop EOL Node versionsTest plan
npm run buildpasses with zero TS errors