The @classic
class decorator (provided by the ember-classic-decorator package) helps you keep track of code that still contains various classic Ember idioms and features that should be migrated away from. Whenever you see a class marked with @classic
, you know that it needs a developer to review it to check for legacy code, and if that code exists, refactor it.
The @classic
decorator workflow has two steps:
@classic
decorator from your app by refactoring classic code.Native class syntax is one of the most anticipated new features in Ember Octane. Ember has always felt like a layer on top of JavaScript, and a huge part of the reason for that is the Ember Object Model, the class syntax that shipped as part of Ember from the very beginning.
Being able to use a mostly-vanilla JavaScript syntax for these classes, which represent a large portion of most app code, is exciting! Better yet, since native syntax is ultimately just a new syntax for doing exactly the same thing, there's a codemod that can automate most of the conversion for you!
However, native classes are only one of the new idioms introduced in Octane. Even after converting a class to native class syntax, there are a few additional changes you should make:
Remove usage of EmberObject
class methods.
Even though you are using native class syntax, you still extend from the EmberObject
base class, which has methods like get
, set
, incrementProperty
, extend
, and create
. These methods are not necessary to use in Octane, and will likely be deprecated in the near future, so it's recommended that you remove any usage of them. The full list is:
get
set
getProperties
setProperties
getWithDefault
incrementProperty
decrementProperty
toggleProperty
addObserver
removeObserver
notifyPropertyChange
Note that you can still use the functional versions of these methods, just not the ones provided by the class itself:
class MyComponent extends Component {
@action
updateValue(newValue) {
// 🛑 this should be removed
this.set('value', newValue);
// 👍 This is ok
set(this, 'value', newValue);
}
}
Convert from init
to constructor
.
init
is in many ways similar to the standard JavaScript class constructor
, but it is actually a lifecycle hook that runs after the object has been constructed. In most cases the hook can be renamed to constructor
without any further changes, but there are sometimes subtle differences, so they generally require additional attention.
Remove all mixins. Mixins are another classic class feature, and they will likely be deprecated in the post-Octane world. Removing them from your codebase will help to future-proof your app, and generally improve the maintainability of your app in the meantime. (See Converting Classes with Mixins for guides for migrating the many mixin-based patterns in Ember apps.)
Rewrite Classic Components and Utility Classes entirely.
Today, all classes extend from the EmberObject
base class. Classic components rely on some intimate details of the EmberObject
base class which cannot be changed, and this is part of the reason Glimmer components were introduced, so they should all be converted in time to Glimmer components.
In addition, you may sometimes have written a class that wasn't a component, route, model or any other framework class. If you ever have directly extended EmberObject
, then this is a utility class. This was done commonly before native classes were supported since there was no way to use Ember features with native JS syntax, but now that there is this is no longer needed. This classes should be rewritten so they don't extend from EmberObject
at all anymore, and instead are plain native classes with no base class.
Keeping track of all of these additional changes is a large task, but we've tried to make it easier with the @classic
decorator!
Adding the @classic
decorator to a class:
init
, not constructor
, via lintthis.get
, via lintClasses without the @classic
decorator:
constructor
, not init