 Hello everyone and welcome to EmberConf 2020. Now I can't see any of your faces, but I can already tell that you're virtually brimming with excitement for this year's talk, so let's get started. When I talk about the octane octopus, what I'm referring to is this idea that because octane represents so many new features being introduced into the Ember ecosystem that it's going to be a daunting task to migrate your existing code onto octane itself. However, I'm here today to show you a migration path that not only breaks down the migration into individual cohesive steps, but also allows you and your team to stay productive building new features in octane even before your existing code is finished migrating. So a little bit about myself. My name is Jordan Hawker. I'm a staff front and engineer at LinkedIn. I've been working at LinkedIn for about a year and a half, and this is my dog Cooper. He's an Australian catalog four years old and he's absolutely adorable, so you get a picture of him. I work on the LinkedIn talent solutions team at LinkedIn and we build products to help people build teams. So we have a bunch of different features to our platform, including talent insights, job postings, candidate sourcing and so on, all of which are built with Ember. We maintain three different applications just within our organization and we have nearly 50 internal add-ons that solely power these applications in addition to dozens more add-ons that are either supported company wide or come from you, the community. So why is the migration experience itself important? Well, past migrations have sucked, as many of you probably know. If you have existing code, it can be a daunting task to figure out, how do I actually adopt new features? Many of you have been in the community for a while, maybe remember going from Ember 1.0 to Ember 2.0? That took a while. There were a lot of big changes that had to be incorporated and I think one of the great things about the Ember community is that we continue to learn and improve every time we go through a process like this and I think Ember octane is the epitome of that. It's important to make sure that your application stays stable throughout the entire migration process so that you're not introducing regressions as you're trying to refactor your code. And additionally, because teams are always trying to deliver new things while they're upgrading their code, it's important to stay productive and we need a migration process that supports that. Now for those of you who don't yet know about octane, I'm going to give you a little bit of background here. I'm sure you're about to learn a lot more about that throughout Ember comp. So here's just a brief primer. So octane is an addition of Ember that represents a set of new features meant to fundamentally modernize and improve the way that we write Ember applications. Why should you migrate to it? Well, it adopts a lot of modern JavaScript features and it brings in new patterns that streamline components, state management, and a lot of the other ways that we think about our Ember applications. In addition, octane is interoperable with classic Ember patterns so you can continue new features in octane while you're migrating off of your old classic Ember code. It's important that as a community, we cross this bridge together so that everyone has the opportunity to end up in octane and adopt the features that they want to bring into their application. So there are a lot of different features included in the octane edition and you're going to learn a lot more about them this week, but here's a brief list of what you have to look forward to. Google Bracket syntax, native classes, named arguments, ES5 getters, modifiers, glimmer components, and tracked properties. Now when we thought about tackling octane migration for our code base, we had to design an approach that fit our team and I think that talking to members of the community and talking to people on the core team, we have a lot of the same goals in mind. So what is it that we actually want to accomplish as a community as we're migrating to octane? Well, we want to unlock new features quickly. You know, everybody has the opportunity to use new features if we make them available in the code base and that's a great way to improve developer happiness. Additionally, we want to reduce the manual or factoring cost. Anything that can be automated should be automated. Additionally, we need to minimize the overhead of learning new patterns. We don't want to dump a ton of new stuff on our developers all at once. It's better to be able to introduce things in chunks so that people can get used to the new way of writing code in Ember. Also, many of these teams are likely using limited resources for their migration efforts. We're all trying to deliver features and we can't afford to just make the entire team stop what they're doing, spend a bunch of time on migrating and then not make any progress on our own deliverables. So we want to design a migration path that allows us to move forward incrementally with limited resources. Additionally, something that's very important for any sort of migration or refactoring is not to introduce too many logical changes into how your code executes. And that's something that octane does very well because a lot of the changes introduced in octane are just AST changes. It's improved syntax. It's streamlining the way that we write the code without fundamentally changing the way that you think about building Ember applications. And that's important because that allows your teams to adopt these new patterns and stay productive the entire time because at the end of the day, when you're thinking about how to architect something in Ember, that's not going to change significantly. You're just going to be doing it in a way that is more lightweight and streamlined and easier to understand. So how do we break this down for a piecemeal migration? Well, the first thing that we had to ask ourselves was, when are these octane features available? So many features were introduced over time throughout the 3.x series. Most of them are polyfilled and stable back to Ember 3.8. And all the features were finally available in Ember 3.15. This is important to note because add-on authors may be trying to support older versions of Ember, but at the same time, they want to upgrade to Ember octane and be using all of these nice new features. Well, because there are polyfills that support these features back to older versions of Ember, add-on authors can actually start updating to octane today, even if the apps that are consuming them aren't on Ember 3.15 yet. Now, for us, we started about six months ago. At that time, I want to say Ember 3.12 was the latest in Ember. And we had to figure out what it was that we were going to do in order to get to the octane standard. So we decided that coming from Ember 3.5 at the time, we were going to upgrade to Ember 3.8 and take the approach of trying to adopt polyfills so that we could get features sooner. And then that would allow us to start using these features in our production code as we were finishing the rest of the migration to Ember 3.16, which would be out by then, and getting all of our components converted to Glimmer and so on. So that was a decent plan. However, things have changed a little bit since we initially created that plan. So I want to talk to you all about what we would recommend now if you're starting an octane migration today. And I'm going to break that down for you into about four phases that allow you to cohesively accomplish a particular goal and then start working on the next phase of the migration while you reap the benefits of those changes. So the first thing that you can do is upgrade to Ember 3.16. It's the latest LTS. There's no polyfills needed. And because it's an LTS, that means that you're going to have long-term support from the Ember community for security fixes and bug fixes and that sort of thing even while you're continuing to go through your migration steps. So the next thing you want to do is enable octane features. Now, all of these really are opt-in when you're ready. So you don't necessarily have to adopt them all at once. However, if you do adopt all of them, that's what the Ember guides have been written for in octane. And so that's where we're guaranteeing the best possible experience with the way octane has been designed to work together. A few of the features that you're going to be looking into at this stage are disabling the implicit application wrapper that went around classic Ember applications, enabling template-only glimmer components, enabling async observers, and installing the packages for glimmer components and glimmer tracking. Now, for those of you who are using Ember CLI Update, the blueprints for new Ember apps actually include all of these changes. And so running Ember CLI Update as your path to get your application into the latest version of Ember will also add these changes in for you as part of the process. Now, the next phase here is running code mods. Now, while you're doing these code mods, keep in mind that you've already enabled a bunch of octane features. So your team can already be using these features for new code even while you're code modding your existing code. And that's very important because it allows you to start building new features in octane without having to go ahead and worry about creating new tech data from the features that you're delivering in the middle of the migration. So there are a lot of great code mods out there provided by the Ember community, most of which can be found in the Ember code mods organization on GitHub. There are five that are important to call out here as part of your octane migration. However, component template co-location, angle bracket syntax, no implicit this, which is a code mod for named arguments, ES5 getters, and native classes. So all of these are important new features that have changed about the way that we write and organize our Ember code. And you can automatically update your existing code to use these patterns via these code mods. So once you've completed phase two, you've now gotten to the point where most of the syntactical changes to your code have taken place. The stuff that is fairly easy to just one-to-one translate via an automated code mod. And at this point, your team is already able to use all of the octane features for any new code. So now you need to start thinking about how do we rewrite some of our classic Ember classes in order to adopt some of the new fundamental changes in how we write octane codes such as Glimmer. So we're gonna start removing classic patterns from our code. And remember throughout all of this, you're still being productive, but your migration is gonna go back through your existing code and just take care of a little bit of cleanup here and there. Now, there's an at classic decorator that gets automatically added by the native class code mod to help ease this migration. Now this decorator essentially tells the linter to allow or disallow certain classic methods such as get set, get properties, set properties, toggle property, increment property. And it also enforces the use of a knit over constructor for super classes. So this decorator essentially allows you to keep using the classic way of defining our classes and interacting with them. And what you're going to want to do is go through and progressively convert all of these at classic decorators into modern native classes. And anything that you've built yourself that uses Ember object as a base class, you're gonna want to update that to use native classes and constructors. The next thing you're gonna wanna do is remove any other classic Ember patterns that you might have such as observers, event listeners, and mix ins. These, for the most part, are patterns that have been in decline in Ember for a while, but in Octane, we don't use them at all. So this is an opportunity to rethink the way that you interact with that functionality and write it in ways that fit within the Octane ecosystem. The third thing that you're gonna wanna do here is take care of your template-only components. Now, when you turned on the template-only glimmer components, that actually runs a code mod in the background that creates a backing class for any of your existing template-only classic components. So anywhere you had just a .hbs file without a paired JavaScript file for a component, the feature enabling will actually take care of creating just an empty JavaScript class for you. And this is important because that means that from now on, any solo templates that you have in your components folder are actually glimmer components. And that keeps the framework from getting confused between what is a classic template-only component and what is a glimmer template-only component. So in order to get rid of these classic template-only components, you're gonna want to remove that backing class and then remove state mutations from helpers like Mute and you're gonna wanna remove any two-way binding that you're relying on in your templates. Now, this is a great way to really get started with using glimmer components because template-only components are the easiest to understand in terms of going from classic to glimmer because there's not a huge shift in the way we think about templating and there's not a huge shift in the syntax other than moving to angle bracket syntax which you will have already done with your code mods. So once we've gone through all of that, you're going to be at a point where you're ready to start writing your components and classes in glimmer. So glimmer is great because it's going to provide you a lighter, more streamlined experience for your component interfaces. For example, there are something like 23 lifecycle hooks in classic Ember components today and in glimmer there are only, I believe two. So it's a lot easier to understand how the lifecycle of a component flows in glimmer compared to the way we had designed classic Ember components. So as you're bringing your old code up to your new standards, the first thing you want to do is do some preliminary component refactors. Any classic components that you have, you're going to want to migrate them to an empty tag name. Now, most of you know that classic Ember components allow you to define a tag name that sets the type of the wrapping element of Ember components. This element is not shown in your component template, but it does get rendered to the DOM, which can be kind of confusing for people who haven't been using Ember for a while. So glimmer gets away from this entirely by allowing you to just render what you need in the template. So by migrating your classic components to an empty tag name, moving all class name and attribute bindings into a new root element that wraps your template, and then migrating methods like click and moving any DOM manipulation to modifiers, you can eliminate any of that magic binding to this mythical wrapping element that you had before. So the other thing that you're going to want to do here is migrate action to on an FN modifiers, which are two new modifiers provided within Octane that give you a more explicit descriptive way to handle actions. The final thing that you're going to want to do after this is actually finish your glimmer conversion. So now that you've prepared your classic components to be converted, you're going to go through and start converting lifecycle hooks from classic to glimmer and convert your computed properties and dot set calls to use tracked properties. You're also going to want to do this in your non components such as routes, models, controllers, et cetera, by finding any computer properties you have in there and converting them to track properties as well. At this point, you're done. You've gone through and you have adopted this lighter, more ergonomic component interface and you have streamlined the way that you write your Ember applications. So at this point, you've adopted all of the modern Ember features and throughout this entire process, your team has already been building new code in Octane. And that's how we create this migration in a way that allows you to assign limited resources to that project without significantly impacting your team's productivity. So let's talk about the next steps here. If you want to start an Octane migration today, what does that actually look like? Well, I've put together a bunch of resources here today for tackling it yourself. The first thing I'm going to recommend here is that everyone who is interested in migrating to Octane should join the topic Octane migration channel in the community discord. That's a great place to raise questions and ask people about how they're going about this process. I also recommend checking out the new redesigned Octane guides which replaced the classic Ember guides. A lot of work has been done by the learning team to make these very easy to understand and to really help people dive right into Octane from the very beginning. Now, this talk roughly follows the recommended Octane migration guide in the Ember Atlas. So I recommend looking at that resource to get a more in-depth look into each of the individual steps that I've talked about today. There's also a great classic versus Octane cheat sheet that allows you to get a side-by-side comparison of what a particular syntax looks like in classic Ember versus Octane. And that's very useful because you can very quickly say, okay, I want to do something. Here's how I would do it in classic Ember and then it'll show you how to do it in Octane. If you want to learn more about some of the new features in Octane such as glimmer or track properties or modifiers, I recommend checking out one of the many blog posts that have been written about Octane over the last year. In particular, Chris Garrett has a series called Coming Soon in Ember Octane that he wrote last year that dives into many of these topics in depth and really helps you understand what's great about these features, why they're important to Octane and how you use them. And finally, as I mentioned before, definitely check out the Ember code mods organization on GitHub because that's where you're going to find nearly all of the code mods that are going to help you as part of your Octane migration. So there are a few key call-outs I want to finish on here. The first thing you're going to want to do is upgrade to Ember 3.16. It's the LTS. It's going to give you the longest term stability of staying on a single version of Ember while you're going through this migration. Secondly, you're going to want to octaneify your code. So opt into the features that you want and let those code mods start migrating while you're already able to use octane features today in new code. That's super, super important for keeping your team productive. So the one thing I want to leave you with here is that logically you're building the same Ember app. So it may seem daunting, but at the end of the day, when you think about how you're putting together components and routes and services and how everything interacts together, it is the same fundamental concepts that you have in classic Ember in octane. But at the same time, you're gaining a lot of benefits of the way that octane has streamlined the way that you write your code. So you're going to learn a lot about this throughout the rest of Ember Comp and hopefully now you have the tools to actually know how to tackle this migration. That's all I have for you today. Thank you so much for joining me. Again, my name is Jordan Hawker. You can find me on Twitter or GitHub. And if you'd like to check out a copy of the slides, you can go to jhawk.co slash emberconf20. Thank you very much and enjoy the rest of your conference, everyone. Thank you.