Repository navigation
chore: fully specify config-graph imports for native ESM resolution - #16
Merged
JakeGinnivan merged 1 commit intoSep 2, 2026
Conversation
Vite 8 warns that the config module graph uses features unsupported by `configLoader: 'native'`, which is planned to become the default. Nothing is broken — the default `bundle` loader resolves these fine — but the warning fires on every dev and build invocation, and the underlying incompatibility is real. Rather than suppress it via VITE_CONFIG_NATIVE_IGNORE_WARNING, fix the imports so the config graph resolves as genuine Node ESM: - Add explicit `.ts` to relative imports across the config graph (conference-stub, themes, theme-builder, vite.config.ts). Matches the existing convention in website/e2e/, which Node already runs directly. - Move @ddd/conference-config to module/moduleResolution NodeNext. It's an extracted library, so resolving it as real Node ESM rather than through a bundler's lenient lookup keeps it honest; bundlers understand the fully specified form too. - Add allowImportingTsExtensions to the conference-stub tsconfig (already noEmit, so nothing is rewritten on the way out). - Widen the theme-builder module-boundary allowlist to accept an optional `.ts`. It anchored on the bare specifier, so adding the extension would otherwise resurface the boundary error in conference-stub's themes. Also fixes one case the warning cannot report: `safe-routes/vite` is a bare specifier, and Vite's compat check only scans relative imports. The package ships no `exports` field, so native Node ESM cannot resolve the extensionless subpath and the build fails outright under the native loader. Import `safe-routes/vite.js` instead. conference-stub is the seed /new-conference copies for each new fork, so fixing it here keeps new conferences from inheriting the warning. Verified: tsc -b --force clean; 328 tests pass; lint 0 errors across all 3 projects; vite build emits no warnings; `vite build --configLoader native` now succeeds; and the stub and lib graphs each import cleanly under native Node ESM. Claude-Session: https://claude.ai/code/session_012ZUK9WJ1TGNQzBSNwwrBx1
JakeGinnivan
deleted the
jakeginnivan/esm-extensionless-imports-nodenext-resolution
branch
September 2, 2026 03:28
JakeGinnivan
added a commit
that referenced
this pull request
Sep 8, 2026
`setup` fans out to four generators with no ordering, so nx runs them
concurrently — and all four write into `website/`. `react-router typegen`
clears and rewrites `.react-router/types/` as it goes, so its rmdir can hit a
directory another generator has just repopulated:
ENOTEMPTY: directory not empty, rmdir
'.../website/.react-router/types/app/routes/+types'
That kills the visual-regression job before it takes a single screenshot. It
hit three PRs in a row (#16, #17, #18), each going green on a plain re-run,
which is what a race looks like rather than a real failure.
`parallelism: false` on the four setup targets serialises them. Verified by
running `nx setup` from a clean tree and again over existing generated output
— the repeat run is the case CI was failing on.
This is a stopgap: the targets are still unordered relative to each other, and
the workflow additionally runs `nx setup website` explicitly even though
`e2e-visual` already dependsOn it, so setup runs twice per job. Worth tidying
properly, but serialising fixes the flake now.
Claude-Session: https://claude.ai/code/session_019eNk5wET3eWEqRFFtLihTV
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.
Why
Vite 8 prints this on every
devandbuild:Nothing is broken today — we're on the default
bundleloader, which resolves extensionless imports fine — but the warning is noisy and the underlying incompatibility is real. Rather than silence it withVITE_CONFIG_NATIVE_IGNORE_WARNING, this fixes the imports so the config graph resolves as genuine Node ESM.The warning only scans the config module graph —
vite.config.tsand what it transitively imports at config-load time:vite.config.ts→conference-stub/build-manifest.ts→manifest.ts→config/years-index.ts→ the year files → venues.conference-stubis the seed/new-conferencecopies for each new fork, so fixing it here stops every new conference inheriting the warning.What changed
.tson relative imports across the config graph (conference-stub, themes,theme-builder,vite.config.ts). Matches the existing convention inwebsite/e2e/, which Node already runs directly.@ddd/conference-config→module/moduleResolution: NodeNext. It's an extracted library, so resolving it as real Node ESM rather than through a bundler's lenient lookup keeps it honest. Bundlers understand the fully specified form too.allowImportingTsExtensionson theconference-stubtsconfig (alreadynoEmit, so nothing is rewritten on the way out). Deliberately not added where it isn't required —nodenextaccepts.tsspecifiers undernoEmiton its own.theme-buildermodule-boundary allowlist to accept an optional.ts. It anchored on the bare specifier (.../theme-builder$), so adding the extension would otherwise resurface the boundary error inconference-stub's themes. This was caught the hard way downstream — it turned the fork's CI red.One case the warning cannot report
Vite's compat check only scans relative imports, so this stayed invisible until the config was actually run under the native loader:
safe-routesships noexportsfield — justmainplus a barevite.js. Native Node ESM needs the explicit extension for that subpath. Now importssafe-routes/vite.js. Had we only suppressed the warning, this would have surfaced as a hard build failure on a future Vite major.Verification
tsc -b --forcenx run-many --target=test --allnx run-many --target=lint --allworker-configuration.d.ts)vite buildvite build --configLoader nativeThe
--configLoader nativerow is the point: this is compatible with the future default, not just quiet about it today.Relationship to the fork
This is the core half of dddwa/dddperth#151, which landed the same change for the fork's
conference/layer. The fork carries its own copy of the eslint allowlist (one level deeper,core/website/...), fixed there separately. Forks will pick this up on their next/pull-upstream.https://claude.ai/code/session_012ZUK9WJ1TGNQzBSNwwrBx1