 Hey, my name is Casey Coughlin. I am a UI developer slash designer at LinkedIn. We, too, are also hiring amazing people. Can I get around for all the LinkedIn employees that are right here? Who all works for LinkedIn now? So yeah, we work with Ember Engines. My team specifically has been working in Ember Engines for the last eight months now. Granted, they are still experimental. They are still not fully sanctioned by the Ember powers that be. So with that, you run into a few issues. But nothing a good engineering team couldn't handle. So in case you're not on Canary, on the bleeding edge, as we might be, and not everybody can, maybe you don't know what engines are. Maybe you haven't read up on engines yet. So essentially, an engine is like a little app inside a larger app. They're a lot like add-ons, but they'll have one point of entry into them, and they can either be a routable or not routable. But they work a lot like add-ons with a few things that are different. So for context, for our world, I mean, engines can be within their consuming app or outside. For context, for my specific engine, we are outside of the consuming app. We are two different code bases entirely, and so our consuming app just pulls us in like any other add-on. So great. We've worked with add-ons before. We are comfortable pulling in Ember add-ons. What could go wrong? Well, it turns out a couple things. Again, like I said, they're not entirely just like add-ons. So we ran into a few issues, and I'm just going to share a couple with you tonight and how we got through them. SAS compiling, unit testing, because that's always fun, and dependencies, of course, dependencies. So first up, at LinkedIn, we use eyeglass for our SAS compiler. And there is a handy little Ember CLI eyeglass add-on. Great. We pull it in. Everything works unless you're an engine or an add-on. In which case, it just kind of throws up. It doesn't compile on build, and it just throws a bunch of errors. So we dug through this. And this specific issue, I don't believe is specific to engines. But going through the code, it turns out that eyeglass just looks in the app directory for its styles to compile. And if you're an add-on or an engine, you don't have an app directory. You have an add-on directory. So how did we get through this? We modified our package.json. We removed the Ember dependency entirely, and then wrote an eyeglass exports.js file to kind of tell eyeglass where to look in the add-on directory for styles instead of app. And then we modified our consuming apps package.json to bring in. And then they just import our styles as you would any other add-on SCSS. So great. We get through that. We get our compiler in. We're writing styles. Everything's great. Except we can't run unit tests, like at all. And you kind of need unit tests. So running our unit test, just plain old out-of-the-box unit tests, foo exists, what you get from generating any route or any file in Ember, out-of-box just doesn't work. So we dig through the code again and find out that not only do you need a special Ember engines resolver, but if you're on Canary and you're pulling in your environment variables everywhere and you're linking to module prefix, engines can't find the module prefix either just yet. So we have a little workaround for that as well. We modified the dummy apps resolver to bring in Ember engines resolver. And then we also, for right now, for the time being, we are hard coding the engine's name into the helper resolver instead of linking directly to the model prefix. So great. That gets everything running. But oh, wait. We still have dependencies to manage. And if anybody, if you've worked with Ember or anything, MPM related at any length of time, you know how fun dependencies can be in keeping them up to date, let alone when the app you are working on is itself a dependency for the consuming app. But even worse is when your dependencies are for testing. For the most part, your engine's dependencies, you can have separate from the consuming app and vice versa. You can even inherit dependencies from your consuming app. But this all goes out the window if your dependencies are based around testing as are the ES lint dependencies. So if you're using ES lint, you're probably familiar with the Airbnb config. My team working on the engine managed to find a different Airbnb config than our consuming app, which I didn't even know there were two. And so we're both extending separate config files. This causes problems when you go to run your test because when you build the parent consuming app, it wants all the dependencies for the test for the dependencies, which is our engine. And if our engine is extending a different ES lint dependency, then you run into problems. So this was kind of an easy fix. We just pull in the same thing. For the most part, like I said, they run kind of like add-ons and you can have separate dependencies, but anything around testing, when you're testing and building the consuming app, it needs to be exactly the same as the engines because not only do you need your engine's test to pass, you need the consuming app's test to pass, and they need to pass with the engine in the consuming app, which is kind of three or so levels deep, but there you have it. That is just a little bit into the struggles that we have been digging through in the last six months with Ember engines. If there's any questions, I will take them now. Yeah, so there is a fix. I know, well, not necessarily a fix, but I know it's in GitHub now for the model prefix. So I don't know when that'll be pulled in, but I mean, it's known and there's an issue on GitHub, and so like most things, it'll probably just be a matter of time. We have it to do in our code to revert it when it comes out, but yeah. Yep. Hey, Casey. Thanks for the talk. It's always been enlightening. I was wondering about the recent announcement that Ember engine stuff is now in 2.8 beta, and how much more stable is it, and what does it mean for us? So my apps are still on 2.7. I can't speak to 2.8 just yet, but I'm gonna go out on a limb and say it's great. We got time for one more. All right, one more in the back. Hi, can you talk a little bit about what you were trying to achieve or what problems you were trying to solve by investing in engines? Like what is the thing that you were trying to get out of it? Okay, so I work on internal tools, and we have a lot of tools inside LinkedIn, and they've kind of sprouted up as they do one by one, and they all have their own different look and feel. So we've decided to, as we're rebuilding them, build them all to look like the same tool. And for some tools that really kind of link from one to the other, like our CI tools, they should really kind of look the same, but also more or less be the same. And so instead of having two separate tools, we're testing out the idea of having one tool living inside the other. Since they essentially just link from one to the other, it makes sense to have this so you don't lose context to just be in the same tool. But since we are still two separate teams and we have two separate code bases, two separate backends, we're making different API calls, our options were either Ember engines, or we could do like an Ember app in an iFrame, or we could just leave it separate apps and just have them linked to it, and the user has to just click back and forth between these two totally different sites and apps, which feels jarring and it doesn't feel great for the user. So we went the Ember engines route, and so far it's, I mean, these are the biggest problems we've come across, but for the most part, it's been pretty smooth sailing. Everything makes sense, and it works pretty seamlessly together, and from a user point of view, it's all the same, and you don't lose context and it's great. Awesome, thank you so much, Casey.