Skip to content

Migrate test-app to vite (ember.nvp-style), scenario-test via @embroider/try, drop TS 5.9 - #18

Merged
NullVoxPopuli merged 6 commits into
universal-ember:mainfrom
NullVoxPopuli-ai-agent:vite-test-app
Jul 20, 2026
Merged

NullVoxPopuli merged 6 commits into
universal-ember:mainfrom
NullVoxPopuli-ai-agent:vite-test-app

Conversation

@NullVoxPopuli-ai-agent

Copy link
Copy Markdown
Contributor

Follows up on #15. Everything verified locally: full workspace turbo build lint test typecheck green; default suite 163 pass / 1 skip / 0 fail; ember-lts-5.12 (compat) and ember-lts-6.4 (pure vite) scenarios run green end-to-end locally.

test-app → vite

Modeled on pnpm dlx ember.nvp output (qunit + typescript + inspector-support layers):

  • @nullvoxpopuli/ember-vite + (rolldown-)vite 8, ember-source 7, @glimmer/component 2, glint 2 (ember-tsc), testem running the built dist.
  • Strict application resolver with an import.meta.glob modules map; the ember-data store service is registered explicitly (app/services/store.ts) since there's no app-tree merging.
  • Route templates converted from loose .hbs to gts route components typed as TOC<{ Args: { controller; model } }>; ember-page-title dropped; ember-sinon-qunit replaced by a QUnit.testDone(() => sinon.restore()).
  • All the ember-cli/broccoli machinery is gone (ember-cli, auto-import, webpack, ember-template-imports, resolver, load-initializers, config/environment, …).
  • The hbs/classic-reexport smoke test was removed — it specifically exercised loose-mode app-tree resolution, which has no strict-mode equivalent. The _app_ re-exports themselves still ship and are exercised by the 5.x compat scenarios' builds.

Matrix testing → @embroider/try (per ember-cli/ember-addon-blueprint)

  • Scenarios live in test-app/.try.mjs; the Default Tests job emits the matrix via @embroider/try list, and the try job does apply → pnpm install --no-lockfile → pnpm turbo test (with ENABLE_COMPAT_BUILD in turbo's env inputs).
  • ember-lts-5.8 / ember-lts-5.12 swap in @embroider/compat's classic build (own vite/babel configs, ember-cli-build.cjs — which is also where macros own-config must live in compat mode) pinned to vite 7. ember-lts-6.4, latest, beta, alpha run pure vite 8.
  • The a11y acceptance tests (the only route-visiting tests) are gated on ember-source >= 6.3, where component route templates landed; 5.x scenarios still run all 160 rendering/unit tests.
  • Support-floor note: the previous ember-try matrix nominally covered 4.4/4.8, but hadn't actually passed in a very long time. The vite/compat harness bottoms out at 5.8. Peer ranges (ember-source >=4.4.0) are unchanged — older versions are simply no longer CI-verified. Happy to bump the floor in a follow-up if you'd rather the peers tell the truth.

Package changes surfaced by pure-vite consumption

  • ember-async-data ^2 and tracked-built-ins ^4 (their old versions dragged in v1-addon transitives — @ember/test-waiters@3, ember-tracked-storage-polyfill — which can't load outside a classic build).
  • Dropped the @glimmer/tracking peer: at runtime that module has always come from ember-source (the npm package is types-only and lacks cached); the real package shadowing ember-source's copy breaks vite builds.
  • Peers widened: @glimmer/component ^1.1.2 || ^2.0.0, ember-changeset ^4.1.2 || ^5.0.0.
  • Removed "./-private/*": null from the exports map — embroider-vite resolves the dist's relative -private imports through the exports map, so the null entry breaks consumers.
  • test-app: ember-changeset 5 and ember-a11y-testing 8 (both v2 addons), explicit axe-core.

CI

  • TS matrix drops typescript@5.9, keeping 6.0.
  • try-scenarios job rewritten for the dynamic @embroider/try matrix (fail-fast off, per-scenario env).
  • pnpm-workspace.yaml allows esbuild builds (vite 7 in compat scenarios).

Not touched

  • docs-app stays on its classic webpack build for now (docfy/oss-docs are a separate migration).
  • Runtime source of the addon packages is unchanged — everything above is dependency/metadata level.

🤖 Generated with Claude Code

NullVoxPopuli-ai-agent and others added 6 commits July 19, 2026 19:17
…5.9 job

test-app is now a modern vite app modeled on ember.nvp's generated output
(pnpm dlx ember.nvp with the qunit, typescript, and inspector-support
layers): @nullvoxpopuli/ember-vite + (rolldown-)vite 8, ember-source 7,
strict application resolver with an import.meta.glob modules map,
@glimmer/component 2, glint 2 (ember-tsc), testem driving the built
dist. Route templates are gts route-components typed via TOC with
@controller args; the store service is registered explicitly since
strict resolver does no app-tree merging.

Matrix testing follows ember-cli/ember-addon-blueprint: scenarios live
in test-app/.try.mjs and run via @embroider/try (list feeds the CI
matrix; apply mutates the app). ember >= 6.4 runs pure vite; the 5.8 /
5.12 LTS scenarios swap in @embroider/compat's classic build (own
vite/babel configs + ember-cli-build.cjs) on vite 7. ember-try and
@embroider/test-setup are gone; the classic-reexport hbs smoke test had
no strict-mode equivalent and was removed.

Dependency corrections surfaced by the pure-vite consumption path:
- ember-async-data ^2 and tracked-built-ins ^4 in the addon (v1-addon
  transitives — ember-tracked-storage-polyfill, @ember/test-waiters 3 —
  cannot load in a vite app)
- drop the vestigial @glimmer/tracking peer: that module is provided by
  ember-source at runtime (the npm package is types-only and lacks
  `cached`), and the real package shadowing ember-source's copy breaks
  the build
- widen peers: @glimmer/component ^1 || ^2, ember-changeset ^4 || ^5
- remove the `./-private/*: null` exports entry: the dist's relative
  imports of -private modules resolve through the exports map under
  embroider-vite, so blocking the subpath breaks consumers
- ember-a11y-testing ^8 (v2 addon), ember-changeset ^5 (v2 addon),
  explicit axe-core

The TS scenario matrix drops typescript@5.9, leaving 6.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ting tests

- In compat builds, macros own-config must be set through ember-cli-build's
  '@embroider/macros' options; babelCompatSupport() supplies the macros
  config from the classic prebuild, so a buildMacros() call there is inert
- Gate the a11y acceptance tests on ember-source >= 6.3: the app's route
  templates are components (gts), which older ember cannot render
  (verified: 5.12 compat scenario passes with the gate, 6.4 passes fully)
- ember.edition octane in test-app package.json (required by the classic
  pipeline the compat scenarios use)
- allow esbuild builds (vite 7 in compat scenarios depends on it)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The typecheck and try-scenario jobs re-run pnpm install (TS override /
scenario apply), which recreates the injected workspace-package copies
without their dist. A turbo remote-cache replay then restores dist into
packages/* but never executes `pnpm run build`, so pnpm's
syncInjectedDepsAfterScripts hook never refreshes the injected copies
and the test-app cannot resolve @universal-ember/* at all. --force makes
the builds actually run (and sync).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The previous commit claimed this but a scenario-cleanup git checkout had
clobbered it before committing. The classic compat scenarios hard-error
without it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pnpm add re-creates the injected workspace-package copies; injection
hardlinks whatever exists on disk, so dist must be present first (later
turbo builds may be cache replays, which never re-sync injected copies).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Injected workspace-package copies are hardlinked at install time, before
dist exists on a fresh CI checkout, and only a real `pnpm run build`
(not a turbo cache replay) triggers pnpm's syncInjectedDepsAfterScripts
hook. Rounds where turbo happened to cache-miss passed; cache hits broke
every consumer of @universal-ember/* with unresolvable imports.

- composite pnpm action force-builds packages right after install
- floating-deps job forces after its lockfile-less reinstall
- the TS job no longer needs its own pre-build (composite covers it)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@NullVoxPopuli
NullVoxPopuli merged commit bc4cec2 into universal-ember:main Jul 20, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants