Skip to content

Polyfill @ember/owner imports for min-supported scenario#323

Merged
NullVoxPopuli merged 2 commits intoember-cli:nvp/its-vite-timefrom
NullVoxPopuli-ai-agent:fix/min-supported-ember-owner-polyfill
Apr 19, 2026
Merged

Polyfill @ember/owner imports for min-supported scenario#323
NullVoxPopuli merged 2 commits intoember-cli:nvp/its-vite-timefrom
NullVoxPopuli-ai-agent:fix/min-supported-ember-owner-polyfill

Conversation

@NullVoxPopuli-ai-agent
Copy link
Copy Markdown

Summary

Stacks on top of #322. Merge that first.

Unblocks the min-supported try-scenario. With the babel-plugin-debug-macros fix from #322 in place, min-supported (ember-source ~4.2.0) now fails at:

[vite]: Rollup failed to resolve import "@ember/owner" from
".../@glimmer/component@2.1.1/node_modules/@glimmer/component/dist/index.js"

@glimmer/component@2.1.1 has import { setOwner } from '@ember/owner';. @ember/owner as an importable module path didn't exist until ember-source 4.10 (per the @ember/application@ember/owner split deprecation), so there's no resolution on Ember 4.2. Per the upstream polyfill README: "not needed if you are on ember-source 4.12 or newer."

Fix: add babel-plugin-ember-polyfill-get-and-set-owner-from-ember-owner (by NullVoxPopuli) to babel.config.mjs, next to babel-plugin-debug-macros and under the same ENABLE_COMPAT_BUILD gate. It rewrites:

  • import { getOwner } from '@ember/owner'import { getOwner } from '@ember/application'
  • import { setOwner } from '@ember/owner'import { setOwner } from '@ember/application'

@ember/application exports both symbols in every 4.x release, so the rewrite works on Ember 4.2 and remains a semantic no-op on 4.12+ (where @ember/application re-exports from @ember/owner).

     ...(isCompatBuild
       ? [
           [
             'babel-plugin-debug-macros',
             {
               flags: [{ source: '@glimmer/env', flags: { DEBUG: true } }],
             },
           ],
+          'babel-plugin-ember-polyfill-get-and-set-owner-from-ember-owner',
         ]
       : []),

Test plan

  • min-supported (ember-source ~4.2.0) locally → 31 pass, 0 fail
  • Default non-compat → 31 pass, 0 fail (plugin not added without ENABLE_COMPAT_BUILD)
  • min-supported job on CI goes green
  • ember-lts-4.12, ember-lts-5.12, ember-lts-6.4, ember-latest, ember-beta, ember-alpha remain green — setOwner resolution is unchanged for them; the rewrite targets @ember/application which re-exports from @ember/owner in those Ember versions

🤖 Generated with Claude Code

NullVoxPopuli and others added 2 commits April 18, 2026 22:52
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) <noreply@anthropic.com>
`min-supported` installs `ember-source: ~4.2.0` but the test-app's
default `@glimmer/component@2.1.1` has `import { setOwner } from
'@ember/owner'`. `@ember/owner` didn't ship as a module path until
ember-source 4.10, so rollup fails with:

    [vite]: Rollup failed to resolve import "@ember/owner" from
    ".../@glimmer/component@2.1.1/node_modules/@glimmer/component/dist/index.js"

Use `babel-plugin-ember-polyfill-get-and-set-owner-from-ember-owner` to
rewrite those imports back to `@ember/application` (which had `getOwner`
/`setOwner` in every 4.x release). The plugin only runs when
`ENABLE_COMPAT_BUILD` is set, next to babel-plugin-debug-macros. It's a
no-op for scenarios that still resolve `@ember/owner` natively
(ember-lts-5.12 and later) because `@ember/application` re-exports the
same symbols there.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@NullVoxPopuli NullVoxPopuli merged commit 62fbb6c into ember-cli:nvp/its-vite-time Apr 19, 2026
19 of 20 checks passed
NullVoxPopuli-ai-agent pushed a commit to NullVoxPopuli-ai-agent/ember-page-title that referenced this pull request Apr 19, 2026
With ember-cli#323 landed, `ember-lts-4.12` flips to:

    Uncaught ReferenceError: Cannot access 'getOwner' before initialization
    at app-*.js line N

ember-source >= 4.12's `@ember/application/index.js` re-exports the real
implementations from `@ember/owner` as aliases:

    import { getOwner as actualGetOwner, setOwner as actualSetOwner }
      from '@ember/owner';
    export const getOwner = actualGetOwner;
    export const setOwner = actualSetOwner;

`babel-plugin-ember-polyfill-get-and-set-owner-from-ember-owner` rewrote
the source of that import to `@ember/application` — turning the module
into a self-import that rollup then collapses into
`const getOwner = getOwner` (TDZ).

The plugin already tries to skip ember-source paths, but the guard only
short-circuits when the file is outside `.embroider/`; in a vite
compat build ember-source lives at
`node_modules/.embroider/rewritten-packages/ember-source.*/` so it
fell through and got rewritten. Gate the plugin through babel
`overrides` with a `test` filter that excludes any path containing
`/ember-source/`. The polyfill still runs where it needs to
(e.g. `@glimmer/component@2.1.1`'s `import { setOwner } from
'@ember/owner'`, which is how min-supported started passing in ember-cli#323).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

2 participants