We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Migrating an Existing App to Ember, Component After Component

00:00

Formal Metadata

Title
Migrating an Existing App to Ember, Component After Component
Title of Series
Number of Parts
37
Author
License
CC Attribution - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
While Ember is designed for building ambitious applications, the documentation and public resources mostly focus on new applications, making lots of things simpler to write from scratch. This talk will share my experience migrating an existing application to Ember part after part. I'll share tips for how to avoid the unpopular "Big Bang rewrite" (minimizing the costs of adoption), and discuss the integration story and loose coupling of Ember.
13
Thumbnail
07:51
VideoconferencingCodeEuclidean vectorMobile appConditional-access moduleHuman migrationMobile appConnectivity (graph theory)Computer animation
Human migrationDisintegrationData modelMedical imagingEndliche ModelltheorieProcess (computing)Right angleProjective planeSoftware developerInformation securityFormal grammarGame controllerFood energyStrategy gameConnectivity (graph theory)NumberCartesian coordinate systemSheaf (mathematics)NeuroinformatikDifferent (Kate Ryan album)MereologyGroup actionInstance (computer science)Power (physics)Beta functionGraph (mathematics)INTEGRALCodeState of matterContext awarenessTelecommunicationHuman migrationEinbettung <Mathematik>Axiom of choiceComplex (psychology)CASE <Informatik>SoftwareWeightSoftware frameworkGoodness of fitMobile appReliefBitBuildingClassical physicsComputer animation
Menu (computing)Table (information)Bootstrap aggregatingScripting languageComputer configurationMobile appVideo game consoleWordEuclidean vectorTemplate (C++)TelecommunicationTable (information)Web pageCartesian coordinate systemIterationInstance (computer science)Artistic renderingWordBit rateContext awarenessIntegrated development environmentConnectivity (graph theory)Control flowAttribute grammarLine (geometry)Element (mathematics)Computer configurationRange (statistics)Traffic reportingGreatest elementGame controllerService (economics)ACIDConfiguration spaceTheoryStrategy gameBlock (periodic table)Software frameworkUniform resource locatorNumberData structureMereologyArchaeological field surveyBootstrap aggregatingMessage passingForm (programming)GradientLetterpress printingChainState of matterDialectMultiplication signObject (grammar)Right angleMathematicsScripting languageMobile appPlanningRouter (computing)BitKey (cryptography)RootTemplate (C++)Computer animation
Service (economics)State of matterDefault (computer science)Instance (computer science)Process (computing)Set (mathematics)Cartesian coordinate systemResultantMedical imagingMobile appMultiplication signProxy serverWeb pageFeedbackFrame problemTable (information)TheoryEndliche ModelltheorieConfiguration spaceSeries (mathematics)Instance (computer science)Reading (process)Service (economics)Object (grammar)Event horizonPoint cloudProcess (computing)Level (video gaming)Replication (computing)Bootstrap aggregatingCodeState of matterBitMathematicsSelf-organizationDependent and independent variablesTwitterQuicksortReal numberWordTelecommunicationSphereGame controllerGroup actionRight angleParameter (computer programming)Power (physics)Video gameStandard deviationLine (geometry)ChainPlanningInsertion lossSlide ruleBuildingControl flowSoftware developerSubject indexingCore dumpScripting languageMereologyINTEGRALComputer animationLecture/Conference
Transcript: English(auto-generated)
How's it going?
Okay, so migrating an app after component after component. What does it mean? It basically means that you don't always have the choice to rewrite a full application when you want to migrate to Ember. Let's consider that you have another five or seven years old application. This is what we had at people of the company
I work with. We needed to integrate Ember to have more control on our front-end application. We basically couldn't rewrite everything. Before I go deeper into that, allow me a bit of a context of who am I and who I work with. So my name is Xavier Combar.
I'm French, as you can guess, by the accent. And I work at PeopleDoc, which is a French company, also based in the US. We do HR software. So very, very big processes, workflow. We are very heavy on models. And this is why we decided to rewrite our
historic application with Ember. Because it's definitely ambitious, we had a big data model and a ton of feature to work with. So when I entered the company, I've basically been told, okay,
can you Ember all the things? It was my main thing to do. But I had a very, very quick discussion with the project team. And there was no way we could freeze the application, stop working on new features.
We already had a fast-paced development team. And the whole team was composed of Python developers, which own and hate content code. So I had to liberate them from that and start building a number team. But as I said, unfortunately, you can't always start over.
And if you are new to Ember, you will quickly realize by the documentation that by the book, you will have to start with a fresh app, with fresh API and a new project. And this is not always how it goes.
The thing is, for us, the market is very demanding. We were constantly shipping new features, and we couldn't basically afford the six to 18 month offer rights just for our own sake, our own sanity, and for our market as well. So we had to find another way to get Ember
into our stack for more control, for more security, for an even faster development. And while doing that, we had a couple of epiphanies. And if you have something to get out of this talk,
it's basically two things. The first one is the outside world is hostile. When you're in a Ember app, you have amazing tools. You have the run loop, for instance, which you don't have in the outside world,
like in your host app, which makes it very uncivilized to a number of developer. The dome can mutate unknowingly without any kind of forward, or anything. The build process can be very hard to work with as well.
So very, very basically, you all know that computing is all about consuming the time, producing data, so we had to find a way. And what I'm saying for embedding a Ember app
into another stack is true as well for items. It's just about finding the right way of opening your application to the outside world and allowing it to communicate with it. So what we are going to do in this talk, basically, is how to open an API, how to build your app. And you also have to consider,
this is the second, if any, that I'm going to talk about, is that your app is just a component. The component model in Ember is very, very powerful. It's very big. It's a keystone of the Ember 2.x series, and it comes with a lot of best practice,
and they are very, very good, very amazing, most notably data-down action app. And the way we integrated Ember into our existing app is by considering that we just removed a part of the application and replace it with a number app, which in the long run
will only be a component in the bigger app. This is why I called my talk component after component. And there are some key topics that we'll have to face when dealing with Ember, and when dealing with integrating Ember into your app.
Some questions are pretty straightforward, some much less so. Those four questions, like very quickly, are, for instance, what part of the app will you migrate first? What will you start with? There are a couple of strategies that you can apply when embedding a Ember app into and migrating to Ember.
How will you bootstrap the app? Because when you start an app, a classic Ember CLI app, it just starts automatically, and this is not what you do in the general context you want to control when your app starts and where it starts and how it starts
and in which context, in which state, I mean. Then what's the communication workflow? How will your host app communicate with your Ember app? How will you pass data? How will you send orders? How will you make it a whole
and not only an island of Ember into an whole app? And last but not least, the build process. How will you integrate the build process into your existing build pipeline? Well, first thing first, integration strategies. I said there are a couple of strategies you can work with very quickly.
You can go with the most repeated components and the component will find the most in your application. It's a pretty good strategy because it allows you to drag up your code. It's good for interaction-heavy application. Another strategy is to go with the most critical component, the one that brings the most value to your app.
And it's very good safety net when you do business software, as I guess we all pretty much do. You can also go with the most complex component because it's always, for instance,
if I'm taking the worst case scenario of a pure jQuery app with nothing, no framework, nothing at all, and you have a very heavy component, it can really be a mess, it can really be very frustrating to work with, and then just getting rid of that to work with Ember which you know
and can control very precisely, it's also a big relief for the whole team and adding features, it makes it much easier. We basically decided to go with another strategy, is to go with the component that uses you the most and it brings a lot of value to them.
We had a lot of features to add. I know we show that component right now, like an idea of what our page was. We decided to go with a faceted search. So the part on the left, the facets, were basically traits, as we could call them, or facets.
So what is the price range, what is, I don't know, the age for a website, like it could be the price, the rating, whatever, and what we had in this place was,
we had counters, we had auto-updating values based on previously selected facets, so it was fairly heavy, not that difficult, but with all the data updating, requesting new counters and everything, so it can really quickly be a mess.
The search bar was obviously an auto-complete working based on the facets on the sidebar, and the data table was classically a data table with sorting, filtering, adding, removing columns, crazy rendering of some columns, et cetera, et cetera. So the way we did that is we decided to first
change the facets, and the very first iteration of our Amber app was only the facets, and it communicated with the rest of the app, just as it always did, and it allowed us to bootstrap this whole integration thing.
Once that was done, we decided to move the search component into our Amber application, and once that was done, we moved to the data table,
which was by far the hardest part, because the data tables are always very, very hard, and once you've done that, you pretty much have the whole page set up. So once you have done that for one page, for two pages, for three pages, you can basically take over the whole page
and the history, the router, and use the router as well, and then, boom, you have an Amber app. You have a full-blown Amber app, and you have component by component, piece by piece, replaced your former application, like frameworkless or using whatever framework you want with an Amber app.
And this is when you're done. This is when you're done, but this is like, I think it is a strategy that we went with. We are not there yet. We are currently working on the data table, so we are still one step away from that. And we are adding features as well, so it's not always like a straight line.
So you have to consider how you will migrate your app, because it will have a huge impact on the roadmap, and you may have some blocks and some bumps on the road, so please choose, plan ahead your strategy
of how you will integrate your components. The second thing you will have to do once you have decided which component and once you have built, in an isolated way, your components, is bootstrapping. Fortunately, now, with the Amber 2.x series,
we have a lot of very, very good tools, like the Visit API, services are amazing, of course, to handle data and to bootstrap a context, and then the state of your application. So basically, what we did here is take the former app, as it existed before, then we removed all the HTML.
It was a server-side rendered app, so the facets that you see on the left were statically rendered. So we removed all the UL, LI, and everything, and we made it a data structure,
because the whole options available at bootstrap, at least, and all options, the selected options, at the possible values and everything, and replaced that with JSON to the structure. We inserted a script tag, which bootstrapped the Amber app,
and we have an Amber app up and running in our application. This is fairly easy to do, and let me show you a bit more how it works. The tools you have, for instance, are location. You have to set location to none,
otherwise you will have your Amber app take over the router and the history. It can be a pretty big mess. The root elements, select whatever you want, like at the very first step, we just selected the very root element of our former app, of our former facets sidebar.
The app key that you can see above is a pretty nice way to pass options and to bootstrap the state of your application, so you already know that you have this and that and that option already selected, because you mostly, if it is set aside around that app,
you most likely don't have an API at hand, or you don't have a way to handle the state, like a proper way to handle the state, so you just want to throw in data to your app and have it just work like that. And we use actually services to receive
and handle that facets, for instance, object. The visit API is absolutely great, because you can work on multiple pages at the same time and bootstrap them at will. You pass a couple of options, and the good thing is the visit API returns a promise, which means you also keep the control flow sane,
and your host app knows when your Amber app has started, and it allows to change dependencies pretty neatly. It's really good. I have a few words to say on Amber Island. Amber Island is a fantastic add-on built by Mitch Lloyd.
It allows you to basically simulate or do as if you had multiple root elements. So for instance, it allowed us to integrate the search functionality, and how does it work? You just replace your application template
with the Amber Island, and you add data attributes, data component attributes to indicate to your Amber app what components you want to bootstrap and where. There is a way in Amber Island
to pass configuration as a data attribute. I didn't do that. I would not recommend doing that. I want to keep everything under control in the JavaScript world, but that's really up to you, and there are certainly contexts in which it's a good thing to do. Communication, this is a very big topic, because you actually want your Amber app
and your host app to communicate together. As I said, your app is basically just a component, and in the Amber 2 series, we have the data down action app model, which we tried and succeeded to replicate
at the application level. So what does it look like? The whole cloud on the left is your host application, and your Amber application obviously is embedded in it, and what your Amber application will do is just fire events to the outside world.
So it will fire and forget. So your host application knows when something happened, so it can react to that, but what happens in your host app is not the responsibility of your Amber app. This is why an event is good, because you just want to lose control on that.
It's fire and forget, basically. You also want to open as small as possible API from in your Amber app, so your host application can trigger methods and have the state of your Amber application
change accordingly. So with a bit of a code, what does it look like? The slides will be published, so I'm not going very deep into that. This gives me that your Amber application will extend the evented mixin, so it can trigger events.
You will use, well, we used, actually, if you're in another way, just tell me, it's very, it will be very informative. We used an instance initializer, so we could plug the application to a couple of services and trigger events accordingly, and what does it mean in the host app that you can just do myapp.on, for instance,
update facets, and then have the application do some things like reload data table or add data or whatever is needed. So this is basically how we trigger actions, and with the data down sort of thing,
we, well, very simply, we added methods to the Amber application, which was exposed, just exposed globally in the application as well, and so we use the container to look up for the required facet and then trigger the action.
The good thing is, one more, that if you return promises from your method, then you can keep the control flow going and know when everything has happened in your Amber app, and then your host app can keep going, which is a very, very, very nice way to work with
when you have complex workflows. The last thing is the build process. Fortunately for that, we don't have a generic answer, we don't have a definitive answer to offer. It's very, very hard, it's very topic-dependent, it's very context-dependent,
very dependent on the host app on your former pipeline, but fortunately, we have Amber CLI, which is absolutely fantastic, I must say. We can use it from the common line, there is, or you can use it programmatically with the API, so you are pretty much free,
and the whole Broccoli APIs are also available, so if you are lucky enough, you have a Broccoli, Broccoli build pipeline, you can plug the two together. Maybe with Amber CLI, something can be done, but we didn't try it, we'll see.
But if you have something to get out of the build process, it's very hard and you're on your own. For instance, one thing that we found particularly difficult is that the content hooks in the index.html that Amber CLI generates, we didn't handle that
because we had to inject our script tags and style tags by hand in our server-side rendered template, because as I said, it was a render-side, server-side rendered application. So that was pretty hard, but the only thing that it means is that I should invest
more time in Amber CLI, so hey Steph, I heard you. So yeah, this is by far the hardest part of the whole integration thing, because it's really, really, really dependent
on how your existing build works, but once it's done, it makes the whole development and integration thing much easier, much easier. So basically we've seen that you can bootstrap an app, an Amber app within an existing app, have it communicate, have it built.
So yeah, good news, you can migrate all your existing apps to Amber, you have all the tools you need, and I am very, very glad that there's gonna be a learning core team, because I have a lot of things to say to them, I would love to contribute more
on how to migrate an existing app to Amber, because there are a lot of things to be done, there are a lot of very, very ambitious applications which don't currently use Amber, and which will benefit a lot from using it. So that's pretty much it for the talk.
Thank you for listening, and yeah, you can ping me on Twitter, GitHub, wherever you want, if you want to talk, or provide me with some feedback about your current situation. Thank you very much.
Hi. Once you've gotten to that final step where you've migrated all of your individual components, and you're ready to migrate the entire page to Amber, do you find that there is a lot of cleanup to be done to kind of remove all of these hooks and this communication that you've built between the host and Amber, or is it pretty quick
and seamless to take that last step and say this is now a full-on, well-built Amber app? Yep, the whole API thing, yes, we removed it, but that was just basically removing the method that we opened to the world. We use services as a proxy between the Amber app,
well, no, not as a proxy, but we use services a lot to handle the state and data and everything, and so once, for instance, the bootstrap used a lot of JavaScript object, JSON object,
what we did, as soon as we had an API, we replaced the reading of the configuration by the API within the services, in the service, and we were basically done. So along the road, we shifted from a configuration-based state to an API-based, and then it was a lot of juggling,
but it went pretty smooth, to be honest. Thank you very much. Thank you.