Repository navigation
Spike: deprecate EmberObject (RFC 1234) - #21674
Draft
NullVoxPopuli-ai-agent wants to merge 3 commits into
Draft
NullVoxPopuli-ai-agent wants to merge 3 commits into
NullVoxPopuli-ai-agent wants to merge 3 commits into
Conversation
Add the `deprecate-ember-object` deprecation and the `EmberENV._NO_EMBER_OBJECT` flag. The flag is a preview of the removal: each deprecated API throws. A class that extends `EmberObject` or `CoreObject` directly reports the deprecation on each construction. The classes that Ember builds on `EmberObject` have a private symbol mark, so `Route`, `Controller`, `Service` and their subclasses stay usable. The mark replaces the internal copy that the RFC describes, because a copy makes `service instanceof EmberObject` false. The object model methods (`get`, `set`, `getProperties`, `setProperties`, `incrementProperty`, `decrementProperty`, `toggleProperty`, `notifyPropertyChange`) report on all classes. An `init` on a subclass of a framework class reports too. The public `computed` and the macros from `@ember/object/computed` are wrappers that report. Ember code imports the implementations, and calls the get and set functions in place of the methods. The test page does not load with all deprecations on, or with the flag on, because test files use `EmberObject` and `computed` at module scope. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NullVoxPopuli-ai-agent
force-pushed
the
nvp/spike-deprecate-ember-object
branch
from
October 10, 2026 14:34
ca7ab41 to
a92fe4f
Compare
Replace `EmberENV._NO_EMBER_OBJECT` with the build-time flag `import.meta.env?.EMBER_DROP_EMBER_OBJECT`, as RFC 1247 (build-time feature flags) describes for sveltable deprecations. The bundler of the app replaces the expression with a literal, so the published build keeps the expression as it is. The test build passes `EMBER_DROP_*` variables through the Vite `envPrefix`. A build has one value for the flag, so the test file registers either the deprecation module or the flag module. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One flag covers the classic features as a group, so that later changes can put more of them behind the same flag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Spike of RFC 1234. CI fails in the modes with all deprecations on. The todo list below says which test cleanups remove that failure.
The deprecation of the
@ember/object/computedmacros moved to #21688, which can land alone. This spike still has its own copy of that part, and a rebase removes it after #21688 merges.What the spike does
deprecate-ember-objectis new in the registry. It is available in 7.5.0, until 9.0.0, and not enabled.import.meta.env?.EMBER_DROP_CLASSIC_FEATURESmakes each deprecated API throw. This is the design of RFC 1247. RFC 1247 names the flagEMBER_DROP_EMBER_OBJECT. This PR uses one flag for the classic features as a group, so that later PRs can put more of them behind it. The published build keeps the expression, so the bundler of the app replaces it.EmberObject: a class that extendsEmberObjectorCoreObjectdirectly reports on each construction.Route,Controller,Serviceand the other Ember classes have a private mark, so their subclasses do not report.get,set,getProperties,setProperties,incrementProperty,decrementProperty,togglePropertyandnotifyPropertyChangereport on all classes. Aniniton a subclass of a framework class also reports.computed: the publiccomputedand all macros from@ember/object/computedreport. Ember code uses the internal versions, and calls the get and set functions in place of the methods.Differences from the RFC
EmberObject. A copy makesservice instanceof EmberObjectfalse, so the spike uses a symbol mark, asMixindoes.reopenandreopenClassare not in the spike. Deprecate classic classes (RFC 1117) #21673 already changes them, with a different id.destroy,willDestroy,isDestroyingandisDestroyedhave no deprecation of their own.deprecateEmberObject. Removal needs the literal read at each site that holdsEmberObjectcode.EmberENVhas no key for it.Test results
Measured on
mainat e436b92.packages/@ember/object/tests/deprecate_ember_object_test.jsALL_DEPRECATIONS_ENABLED=trueEMBER_DROP_CLASSIC_FEATURES=trueTest cleanups that make this easier
A temporary build recorded each call of a deprecated API, with the test and the file of the call. The result: 1377 tests in 151 files use a deprecated API.
EmberObjectconstructionsetmethodgetmethodiniton a framework subclass@ember/object/computedmacrosgetPropertiesmethodcomputedA test can be in more than one row.
1. Page load blockers: 3 files
Only these files use a deprecated API at module scope. They are the reason that the two modes above do not load.
@ember/-internals/glimmer/tests/integration/syntax/each-in-test:EmberObjectinstances at module scope@ember/-internals/glimmer/tests/utils/shared-conditional-tests:EmberObjectinstances at module scope@ember/-internals/runtime/tests/helpers/array:computedat module scope2. Shared test harness: 6 files, 283 tests
One change here clears many tests.
@ember/-internals/runtime/tests/helpers/array(154 tests): the fixture classes extendEmberObjectinternal-test-helpers/lib/test-cases/query-param(95 tests):this.set,appRouter.get('location.path'), andsetPropertiesinsetAndFlush@ember/-internals/glimmer/tests/utils/shared-conditional-tests(13 tests):EmberObjectfixturesinternal-test-helpers/lib/test-cases/application(9 tests):appRouter.get('currentURL')3. Rendering tests of features that stay: 31 files, 282 tests
These need a rewrite to native classes, tracked state and the
setfunction. Mostlythis.seton the test context (127 tests),init(75),EmberObjectfixtures (70) andcomputed(47).syntax/each-test(46)components/contextual-components-test(25)custom-component-manager-test(23) andcustom-modifier-manager-test(10)application/engine-test(20) andmount-test(8):initonEnginesubclassescomponents/link-to/*(51 in four files)content-test(15),components/curly-components-test(12)4. Routing and application tests: 33 files, 179 tests
Mostly
router.get('currentURL')andcontroller.get(...)(90 tests),initon routes (55) andcontroller.set(...)(38).ember/tests/routing/router_service_test/*(61 in eight files)ember/tests/routing/query_params_testand its folder (38 in four files)ember/tests/routing/decoupled_basic_test(16)@ember/routing/tests/location/*(22 in two files)5. Tests of APIs that go away: 80 files, 814 tests
These need no rewrite. Each file needs one
if (!isRemoved)block and an expectation helper, as the classic component files have.@ember/object/tests/*and@ember/-internals/metal/tests/*: the object model itself, 320 tests or more@ember/-internals/runtime/tests/array/*andmutable-array/*:EmberArraysuites that usegetPropertiesandEmberObjectfixtures@ember/-internals/runtime/tests/system/*andmixins/*: proxies and mixinscomponents/classic/*(15 files, 100 tests)Decision that the cleanups need
228 tests define
initon aRoute,Engine,Serviceor classic component.EngineandApplicationsubclasses in tests useinitto register factories. The RFC shows class fields as the replacement for aService, but it does not say what replacesiniton anEngine.Later work
@deprecatedtags in the API docs.🤖 Generated with Claude Code