Skip to content

RFC#1234 & RFC#1247: Drop the public mixin exports with EMBER_DROP_CLASSIC_FEATURES - #21741

Draft
NullVoxPopuli-ai-agent wants to merge 2 commits into
emberjs:mainfrom
NullVoxPopuli-ai-agent:nvp/drop-classic-mixins
Draft

NullVoxPopuli-ai-agent wants to merge 2 commits into
emberjs:mainfrom
NullVoxPopuli-ai-agent:nvp/drop-classic-mixins

Conversation

@NullVoxPopuli-ai-agent

Copy link
Copy Markdown
Contributor

Merge #21726 first. This PR sits on top of it. Review only the last commit, 376ff81830.

With EMBER_DROP_CLASSIC_FEATURES=true, four public mixin exports are undefined:

  • @ember/object/evented
  • @ember/object/observable
  • @ember/object/promise-proxy-mixin
  • ControllerMixin from @ember/controller
const ExportedEvented = (
  import.meta.env?.EMBER_DROP_CLASSIC_FEATURES ? undefined : Evented
) as typeof Evented;
type ExportedEvented = Evented;

export default ExportedEvented;
  • The cast keeps the published type without | undefined.
  • The type alias keeps the type half of the default export, so import Evented still gives the interface type.

Route, EmberRouter and CoreView add Evented to their meta only so that Evented.detect stays true. They skip that step when the flag is set.

Not behind the flag

Export Why
Mixin from @ember/object/mixin 23 test files use it at module scope, so the test page does not load in the flag build
EmberArray, MutableArray, NativeArray from @ember/array 11 test files and the shared array test helpers use them at module scope
Enumerable, MutableEnumerable MutableEnumerable is built from Enumerable when the module loads

Tests

  • The tests of the four mixins skip when the flag is set.
  • tracked-test.js: one test used PromiseProxyMixin, but did not skip when its deprecation is removed. It skips now.
  • New packages/@ember/object/tests/drop_classic_features_mixins_test.js checks that the exports are undefined. It registers only with the flag.

Checks

Mode Result
Default 9234 tests, 0 failures
ALL_DEPRECATIONS_ENABLED=true 9234 tests, 0 failures
OVERRIDE_DEPRECATION_VERSION=15.0.0 8257 tests, 0 failures
Production build 9071 tests, 0 failures
EMBER_DROP_CLASSIC_FEATURES=true 9235 tests, 0 failures

The type checks of the internals and of the published types (with and without stable decorators), eslint, prettier and the docs check pass.

🤖 Generated with Claude Code

NullVoxPopuli and others added 2 commits October 17, 2026 16:06
`import.meta.env?.EMBER_DROP_CLASSIC_FEATURES` is a build-time flag for
RFC 1247. Later changes read it where a classic feature is defined, and
remove that feature from builds that set the flag.

- `ImportMetaEnv` declares the flag for the type checks.
- `EMBER_DROP_` is in the Vite `envPrefix`, so
  `EMBER_DROP_CLASSIC_FEATURES=true pnpm vite build` sets it for the tests.
- CI has a "Classic features dropped" variant that builds and tests with
  the flag.
- The hello-world smoke test sets the flag with a Vite `define` entry, so
  the package-size workflow measures an app without the classic features.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the flag, `@ember/object/evented`, `@ember/object/observable`,
`@ember/object/promise-proxy-mixin` and the `ControllerMixin` export of
`@ember/controller` export `undefined`. A cast keeps the published types,
and a type alias keeps the type half of each export.

`Route`, `EmberRouter` and `CoreView` add `Evented` to their meta only so
that `Evented.detect` stays true, so they skip that with the flag.

The tests of these mixins skip with the flag. One test in `tracked-test.js`
used `PromiseProxyMixin` without a skip for its removal, and has one now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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