Skip to content

ref(build): Switch TypeScript moduleResolution to bundler#21559

Merged
mydea merged 6 commits into
developfrom
awad/ts-module-resolution-bundler
Jun 17, 2026
Merged

ref(build): Switch TypeScript moduleResolution to bundler#21559
mydea merged 6 commits into
developfrom
awad/ts-module-resolution-bundler

Conversation

@logaretm

@logaretm logaretm commented Jun 15, 2026

Copy link
Copy Markdown
Member

A couple of notable changes:

  • Changes our module resolution strategy from node which is deprecated in next releases to bundler which better reflects our own setup.
  • Changes our module baseline to esnext which was already being used all over.

Some changes were required for svelte SDK because it imported non-exportable types, I opted to vendor them instead. Also one minor exception is introduced for TypeScript 3.8 because it does not support bundler module resolution strategy.

replaces #21520

Changes the shared base tsconfig from `moduleResolution: "node"` to
`"bundler"` (supported since TS 5.0, no TypeScript upgrade required).
`bundler` resolution respects package `exports` maps, so deep imports
into non-exported subpaths no longer resolve.

- Replace the deep `svelte/types/compiler*` type imports with
  `svelte/compiler` and a small set of vendored preprocessor types.
- Inline `@sentry/angular`'s `tsconfig.ngc.json` so it no longer extends
  the shared base config — ng-packagr ships an older TypeScript that
  rejects `"moduleResolution": "bundler"` when parsing the extends chain.
- Downgrade `bundler` back to `node` in the TS 3.8 compat scripts, since
  TS 3.8 predates the `bundler` option.
@logaretm logaretm marked this pull request as ready for review June 15, 2026 19:31
@logaretm logaretm requested review from a team as code owners June 15, 2026 19:31
@logaretm logaretm requested review from JPeer264, mydea, nicohrubec and s1gr1d and removed request for a team June 15, 2026 19:31
// older TypeScript that doesn't support "moduleResolution": "bundler".
{
"extends": "./tsconfig.json",
"include": ["**/*.ts", "src/**/*"],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is sad that we have to do this :(
But it seems to be the only way

@logaretm logaretm Jun 16, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, I don't want to go on an upgrade trip and find the lowest possible version of angular build tooling that both works for us and makes the angular SDK build properly without breaking our support range.

We probably need to upgrade this setup at somepoint.

@mydea

mydea commented Jun 16, 2026

Copy link
Copy Markdown
Member

Missing from #21520, which we should IMHO also pull into this PR, are:

  • Remove any node16/similar overrides we already have in place
  • Remove unnecessary lib: [es2020] redundant config in package config
  • Probably also should include the change to nx.json that everything depends on packages/typescript changes, as otherwise this could lead to stale build cache issues in theory

Addresses review feedback: now that the shared base tsconfig defaults to
`moduleResolution: "bundler"`, the per-package resolution overrides are
unnecessary. moduleResolution only affects how we author/type-check the
code, not what consumers receive, and we build everything with bundlers.

- Drop redundant `moduleResolution: "bundler"` overrides that just
  duplicate the base default.
- Drop the `Node16` overrides (node, node-core, tanstackstart, and the
  nextjs/remix test configs) so they inherit `bundler`. Where `module`
  was set to `Node16` for dynamic imports / top-level await, switch it to
  `esnext` (compatible with `bundler` and still supports both).
- Remove redundant `lib: ["es2020"]` entries that match the base.
- Add `packages/typescript/**` to nx.json's shared named inputs so
  changes to the base tsconfig bust the build cache.

`angular/tsconfig.ngc.json` (ng-packagr's older TS), `astro/tsconfig.dev.json`
(ts-node runtime) and browser-integration-tests (internal `@sentry/core/src`
deep imports) intentionally keep their `node`/`node16` resolution.
@logaretm logaretm requested a review from a team as a code owner June 16, 2026 14:43
@logaretm logaretm requested review from Lms24 and removed request for a team June 16, 2026 14:43
logaretm added 4 commits June 16, 2026 11:02
Only node-core actually uses dynamic `import()` (which requires a
`module` of es2020+); node and tanstackstart have none, so they can
inherit the base default. Emitted declarations are unchanged.
Pair the base `moduleResolution: "bundler"` with an explicit
`module: "esnext"` (the canonical bundler pairing — tsc requires a
modern ESM `module` with `bundler`, and only `esnext`/`bundler` or
`node16`/`node16` are valid combinations).

Previously the base left `module` unset, so it defaulted to `es2015`,
which predates dynamic `import()` and top-level await. That forced ~25
packages to each declare `module: "esnext"` and was why node-core needed
its own override. Setting it once in the base makes all of those
redundant, so they're removed.

Only `astro/tsconfig.dev.json` keeps an explicit setting (it pins
`moduleResolution: "node"` for ts-node). Emitted `.d.ts` output verified
byte-identical across all packages.
Setting `module: esnext` + `moduleResolution: bundler` in the base config
leaks into ts-node, which then hands `.ts` helper scripts to Node's native
ESM loader and fails with `ERR_UNKNOWN_FILE_EXTENSION` (e.g. aws-serverless
`buildLambdaExtension.ts`, nextjs `buildRollup.ts`, root `ci-unit-tests.ts`).

Add a `ts-node` override in the root tsconfig pinning `module: commonjs` +
`moduleResolution: node` for script execution. ts-node merges this key
across the `extends` chain, so the single override covers every package
and dev-package that extends the root config. Type-checking / `.d.ts` emit
are unaffected (they use the top-level compilerOptions).
Comment on lines +96 to +100
export interface PreprocessorGroup {
markup?: MarkupPreprocessor;
style?: Preprocessor;
script?: Preprocessor;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The vendored PreprocessorGroup type is missing the name property, which is required in Svelte 4 and 5, potentially causing runtime errors in user projects.
Severity: MEDIUM

Suggested Fix

Add the name: string; property to the PreprocessorGroup interface in packages/svelte/src/types.ts. Then, assign a unique name to the preprocessor objects created in packages/svelte/src/preprocessors.ts to conform to the Svelte 4+ API.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: packages/svelte/src/types.ts#L96-L100

Potential issue: The vendored `PreprocessorGroup` type, which is used to configure
Svelte preprocessors, is missing the `name` property. While the project's tests pass
with Svelte 3, the package claims support for Svelte 4 and 5, where this property is
required according to official types and documentation. If a user integrates this SDK
with a Svelte 5 project, the Svelte compiler may throw a runtime error when it receives
a preprocessor object without the expected `name` property, causing the build process to
fail.

Also affects:

  • packages/svelte/src/preprocessors.ts:1~10

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are internal types, not exposed to users AFAIK.

@mydea mydea left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

niiice!

@mydea mydea merged commit 1a5c64f into develop Jun 17, 2026
273 checks passed
@mydea mydea deleted the awad/ts-module-resolution-bundler branch June 17, 2026 06:50
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