Skip to content

Make ember-lts-4.12 compat scenario runnable#322

Merged
NullVoxPopuli merged 1 commit intoember-cli:nvp/its-vite-timefrom
NullVoxPopuli-ai-agent:fix/ember-lts-4-12-compat-runtime
Apr 19, 2026
Merged

Make ember-lts-4.12 compat scenario runnable#322
NullVoxPopuli merged 1 commit intoember-cli:nvp/its-vite-timefrom
NullVoxPopuli-ai-agent:fix/ember-lts-4-12-compat-runtime

Conversation

@NullVoxPopuli-ai-agent
Copy link
Copy Markdown

@NullVoxPopuli-ai-agent NullVoxPopuli-ai-agent commented Apr 19, 2026

Summary

Gets ember-lts-4.12 green locally by unblocking two stacked runtime issues that surfaced once the require resolver fix in #321 landed. Both only affect the compat path (ENABLE_COMPAT_BUILD=true + the ember4 deps overrides); ember-source >= 6 scenarios don't hit them because the upstream code was rewritten.

1. Cannot read properties of undefined (reading 'has')COMPUTED_GETTERS.has(...)

ember-source <= 5.x (@ember/-internals/metal):

import { DEBUG } from '@glimmer/env';

let COMPUTED_GETTERS;
if (DEBUG) { COMPUTED_GETTERS = new _WeakSet(); }
// ...
assert(`...`, isClassicDecorator || !propertyDesc || !propertyDesc.get || !COMPUTED_GETTERS.has(propertyDesc.get));

@glimmer/env publishes DEBUG = false. Without something resolving DEBUG at compile time, rollup tree-shakes the if (DEBUG) init while the assert predicate still runs eagerly → COMPUTED_GETTERS is undefined at runtime. ember-source >= 6 switched to isDevelopingApp() from @embroider/macros (which buildMacros() already handles), which is why non-compat scenarios don't hit this.

Fix: add babel-plugin-debug-macros conditionally (only when ENABLE_COMPAT_BUILD is set) in babel.config.mjs:

const isCompatBuild = !!process.env.ENABLE_COMPAT_BUILD;

// ...
...(isCompatBuild
  ? [
      [
        'babel-plugin-debug-macros',
        {
          flags: [{ source: '@glimmer/env', flags: { DEBUG: true } }],
        },
      ],
    ]
  : []),

The plugin inlines DEBUG = true at every @glimmer/env import site in ember-source so the init and the use stay consistent. Gating on ENABLE_COMPAT_BUILD keeps the default build untouched.

2. Bump ember-qunit and @ember/test-helpers in the ember4 stanza

Two additional runtime errors were classic-Ember assumptions that don't hold in a vite bundle:

  • ReferenceError: requirejs is not definedember-qunit@8's start() auto-calls loadTests(), which enumerates requirejs.entries from classic Ember's loader.js. ember-qunit@9 dropped that call entirely.
  • Cannot read properties of undefined (reading '_APPLICATION_TEMPLATE_WRAPPER')@ember/test-helpers@4's setup-rendering-context / visit reads global.EmberENV._APPLICATION_TEMPLATE_WRAPPER; classic ember-cli seeded that global from index.html. @ember/test-helpers@5 removed every reference to EmberENV and _APPLICATION_TEMPLATE_WRAPPER.

Both can be worked around in the test app (passing { loadTests: false } to qunitStart, manually assigning globalThis.EmberENV), but the cleaner fix is to bump the pins so the compat scenario exercises the same API surface modern scenarios already do:

 const ember4 = {
-  '@ember/test-helpers': '^4.0.0',
+  '@ember/test-helpers': '^5.0.0',
   '@ember/test-waiters': '^3.1.0',
   '@embroider/compat': '^4.0.3',
-  'ember-qunit': '^8.0.0',
+  'ember-qunit': '^9.0.0',
   'ember-cli': '~4.12.0',
 };

Both bumps peer ember-source >= 4.0.0, so Ember 4.12 is still within the supported range. ember-qunit@9 peers @ember/test-helpers >=3.0.3, so the test-helpers bump stays within bounds.

Test plan

  • pnpm dlx @embroider/try apply ember-lts-4.12 && pnpm install --no-lockfile --ignore-scripts && pnpm --filter ember-page-title build && cd test-app && ENABLE_COMPAT_BUILD=true CI_BROWSER=chrome pnpm test:ember locally → 31 pass, 0 fail
  • Default (non-compat) pnpm test:ember locally → 31 pass, 0 fail (the babel plugin is not added without ENABLE_COMPAT_BUILD)
  • ember-lts-4.12 job on CI goes green
  • ember-lts-5.12, ember-lts-6.4, ember-latest, ember-beta, ember-alpha remain green
  • Non-compat Tests/Floating Dependencies jobs remain green

Still red after this PR

min-supported (ember-source ~4.2.0) hits a separate, unrelated failure: @glimmer/[email protected] imports @ember/owner, which didn't ship until Ember 4.10. The scenario's ember4 deps stanza will need a @glimmer/component@^1.1.2 pin. Out of scope here since the user asked specifically about ember-lts-4.12.

🤖 Generated with Claude Code

@NullVoxPopuli-ai-agent NullVoxPopuli-ai-agent force-pushed the fix/ember-lts-4-12-compat-runtime branch from 83933fa to b60d722 Compare April 19, 2026 02:46
Two stacked runtime issues were blocking ember-lts-4.12 once the
`require` import issue from ember-cli#321 cleared. Both only affect the compat
path (ENABLE_COMPAT_BUILD=true, ember4 deps overrides) and are hidden
for ember-source >= 6 because the upstream code was rewritten.

1. "Cannot read properties of undefined (reading 'has')" at
   `makeComputedDecorator` → `COMPUTED_GETTERS.has(...)`.

   ember-source <= 5.x's `@ember/-internals/metal` has
   `let COMPUTED_GETTERS; if (DEBUG) { COMPUTED_GETTERS = new WeakSet(); }`
   paired with `assert(..., !COMPUTED_GETTERS.has(...))`. `DEBUG` comes
   from `@glimmer/env`, whose published default is `DEBUG = false`.
   Without something resolving `DEBUG` at compile time, rollup tree-shakes
   the init but the `assert` predicate still runs eagerly, so
   `COMPUTED_GETTERS` is undefined at runtime.

   Conditionally add `babel-plugin-debug-macros` (only when
   ENABLE_COMPAT_BUILD is set) with `flags: [{ source: '@glimmer/env',
   flags: { DEBUG: true } }]` so the plugin inlines `DEBUG = true` in
   ember-source. The init and the use stay consistent. Non-compat
   scenarios don't need the plugin — modern ember-source uses
   `isDevelopingApp()` from `@embroider/macros`, which `buildMacros()`
   already handles.

2. ember-qunit@8 + @ember/test-helpers@4 rely on classic-Ember globals
   that don't exist in a vite build: `start()` auto-calls `loadTests()`
   which iterates `requirejs.entries`, and `visit` reads
   `global.EmberENV._APPLICATION_TEMPLATE_WRAPPER`. Both were removed in
   ember-qunit@9 and @ember/test-helpers@5 respectively. Bump those two
   pins in the ember4 deps stanza so the scenario exercises the same
   surface modern scenarios do:

       ember-qunit:          ^8.0.0  ->  ^9.0.0
       @ember/test-helpers:  ^4.0.0  ->  ^5.0.0

   Both peer `ember-source >= 4.0.0`, so Ember 4.12 is still within the
   supported range. ember-qunit@9 peers `@ember/test-helpers >=3.0.3`,
   so the test-helpers bump stays within bounds.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@NullVoxPopuli-ai-agent NullVoxPopuli-ai-agent force-pushed the fix/ember-lts-4-12-compat-runtime branch from b60d722 to 0691d3f Compare April 19, 2026 02:52
@NullVoxPopuli NullVoxPopuli merged commit f231990 into ember-cli:nvp/its-vite-time Apr 19, 2026
19 of 20 checks passed
@github-actions github-actions Bot mentioned this pull request Apr 22, 2026
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