 OK, cool. MBCLI addons is a great blog post about why MBCLI and addons are the next big thing. Ember itself has been working with it for quite a while now. It's just great to be able to move from project to project, bring people on a team or switch them from one company to another and just sit down in front of an ember project and you can just be up to speed pretty much instantly. What MBCLI and MBCLI addons bring to that is the ability to write code that then can ship against multiple different apps and sorts the whole code sharing side of things out amongst various other things. Great post with reading. So MBCLI can do all sorts of things to your ember app, pretty much everything you can do in an ember app. You can then package up, ship out, share with someone else. So routes, controls, views, components can be packaged up, styles. You can add middleware in development for proxies and various other things. All these things will go through the course. I'll basically go through a bunch of different examples from the plugins that are out there. So finding addons, when you generate an addon you get a package.json for MPM. Every one of those comes with ember addon as a keyword. That's how ember CLI knows that something you've installed into the project is an addon. That as a side effect means that when you go to npm.js, npm.js.org, you search for ember addons and you've got them all there. As we've shown a minute ago, emberadons.com is a great place to be able to really easily search and find what's out there and growing every day. So once you've found an addon that you want to install, all you have to do is npm install, save dev, whatever the addon is. Some addons will come with generators to do things like install power packages, install other packages from npm and generally it's ember generate, whatever the addon is. They should say in the read me. And then that's it. You restart your server, you're away. So here's an addon that I wrote the other week that adds HTML sanitisation to an app so anyone can be typing in whatever it is into content-editable areas and you can guarantee that when you're displaying that on the page they've not added dodgy script tags and things like that. So to create an addon, once you've got ember CLI installed, much like creating an ember app, it's just ember addon, whatever the addon name is. It will go through and generate all the files you need. One cool thing, it generates a dummy ember app inside of the test directory so you can develop the addon just in that one place. You don't have to link it to another project to run it. And it also means that all your integration tests run against a live copy of a real ember app. And then pretty much just like building an ember app, you just stick files in the right place and it just works. All the versions of ember CLI meant you had to mess around with telling it where to find certain files, where the trees were, now it's just a case of sticking them in the right place. Things happened. So the convention is there's an addon directory where you put basically all your addon-specific files or components, util, everything should kind of live in there. And then anything you want to be brought into the app that it's installed into, you import and then export again in app. This is an example. So, yeah, ember sanitise, we've got in the addon directory, I've got a util called sanitise.js, which basically is just exports a function that you give it some HTML, you give it a sanitiser config and it spits out sanitised HTML, VTUs. And then in the app directory, there's a helper that then imports sanitise from ember sanitise, util sanitise. So basically everything in the addon's directory gets exported in a namespace of whatever the addon's called so that in your app or from within the app directory in the addon, you can just import from anything from within there. And here we just export a handlebars helper that takes some HTML that's bound to the view, passes it through the sanitise, util, and spits out a safe string. So that's just going to, every time you chain something on the page, it gets run through sanitise. And that's basically it. Once you've installed that, that would just work. Apart from this requires the sanitise.js power package. So you could ask, you could put in your readme say, okay, to use this addon, just add this to your power.json, power install, and you're good, but a bit of a pain. So here you can generate, add a blueprint or a generator, which basically does that for you. So when you run ember generate, ember sanitise, this will add a power package to the project and install it for you. All done. There's similar hooks for add package project, which will add a NPM package. It used to be that the CLI addon itself would, you'd add things in a power.json there or the package.json, and then that would get installed when you install it, but it just led to various nightmares. So now it's basically your apps, package.json and power.json are the definitive source. It makes things a hell of a lot easier. And then in the index.js of your addon, there's an included hook, which basically as soon as the addon is run within an app, this gets called and this gets given the ember app, which is what you have inside of your broc file. And here you can call whatever you want that you would normally do inside of a broc file. So here we're just importing from the bio directory, sanitise.js. So now you can just do what we had on the first slide, which is NPM install, ember sanitise, ember generate, ember sanitise. All done. So there's saying generally you'll add all your addon files in the addon directory and then import and export them in the app directory. What you can also do is if you had an index.js in the addon directory, that's kind of the default namespace. So that then instead of having to import sanitise from ember sanitise, util sanitise and know what the internal structure of the addon is, you can just import and export the bits you want and that's kind of your public interface to the addon. So here in another app, you could just import sanitise from ember sanitise and you don't have to know where things are stored internally. Now for this addon, not really much point there, there's only one util. It's not very complicated, but we're kind of more involved addons. I've got an addon called Fireplace, which is a firebase model library and this has a ton of different things you can import. So models, relationships, stores, transforms, this, that, the other. And if you had to know exactly where it was inside of the addon that these things were stored for you to use it, it's a bit of a pain. So here in the addonindex.js I just export all the things that you should have access to and then when you're using it in your app, you can just import model from fireplace instead of import model from fireplace model model, which is kind of a weird place for that to be. And at some point I'm going to move that and if I hadn't got the index, when I move that everyone's apps would break. So this is kind of your public interface that you kind of maintain and everything else is kind of up for grabs that you can just move things around and know you're not going to break stuff for other people. So another thing you can do is extend configuration so everything in an ember app's config environment there's a config hook in the index.js in the root of the addon which kind of defines everything that addon does. The only thing you need in an index.js is the name but there's a bunch of other hooks included which included the power package earlier is one of them. Config's another takes the environment, modifies it, does whatever it wants to it, spits it back out and anything you have in your environment will override this. So this is from ember CLI, content security policy and this basically sticks into the environment a default set of CSP headers and if it's in dev mode then it adds unsafe eval so that live reload and things like that work. So that's modifying a configuration environment. A different way of doing it instead of hooking into the config hook is you can just stick a file in config.environment.js with pretty much exactly the same thing. Ember Git version does this. So this, when you install this addon it will add into your environment the current version of your application. The current share of your Git repo and also prints it out on the console so if you're sharing it between a bunch of members of a team you know exactly which version of the app people are running. If an error happens you can log that to wherever. You can modify the index.html that's generated. So a fairly new thing is these content for bits of being stuck in the index.html and that means that from your addon you can just stick things into the consumers index.html both for the main app and for test. So there's also content for test head and content for test body so you can inject things just into the test runner. This is how Live Reload works. It takes content for the content for hook. If the type is head it sticks a script tag in there so that Live Reload works. So commands are another thing you can add. So div shot adds a bunch of commands so you can take your Ember CLI app and push it up to div shot. There's similar things about pushing your app up to S3 and various things like that. And this just has an included commands hook which takes an object with the name of the command and all the stuff that that command does. It does a lot. It's worth checking out because it's quite interesting how you can just basically add a bunch of commands to your app. You can post process the tree that's generated at the end of the build. So this is Ember CLI auto prefixer which basically takes the styles tree. So all the CSS that you've written in your app just write it however you want. This will then take that at the end of it and add all the prefixes on make it work for all various different browsers. Again, all you do, Ember CLI auto prefixer and your CSS works everywhere. Dev middleware. So there's a server middleware hook. And this is how, again, the Live Reload middleware works. You get config objects in there which has the app and a bunch of options. And that means any express middleware that you want to use, set up proxies, various things like that, you can just hook in and you're away. So by default, Ember add-ons will look for things in conventional places. So the add-on directory, the app directory will get merged into your app tree, vendor gets merged into your vendor tree. If you want to put them in a different place, you can just override the tree paths. Liquidfire does this because the liquidfire add-on repo is also a fully-fledged Ember app so that you can just clone that, run it and see all the demonstration animations going on there. So obviously app for them is an actual Ember app. It's not the app that you want to be merging into your own app. So here you just override where it's looking for things and you can organize your add-on however you want. You can also override tree for hooks which is the old way that you used to have to do things before the conventions approach. But if you want to store things in a dynamic location or look for certain files based on the environment, then that's a good place to override things. Since the past few versions of Ember CLI, I generally haven't had to touch this and if you look at most of the new CLI add-ons, none of them really do anything with these kind of things unless they're doing band stuff or for backwards compatibility. I think Liquidfire does things like that. So the testing story is basically the same as an Ember app. You've got access to all the same integration unit tests, same deal that you Ember serve in the add-on directory and you get the dummy app being served at localhost 2400 and the tests again run. And that's just the same as developing a regular Ember app. That's a whistle-stop tour of add-ons. Questions? Got some questions. So would this work well for modularizing your app by just saying you want a login thing, a login screen and everything? Would you be able to bring that in? Yeah, so basically you could take any part of your app and just pack it up, stick it in an add-on, put it in a private git repo with its own controllers and everything. Yeah, exactly. Ember admin adds admin areas to Ember apps. That's the name suggests. And that does basically a bunch of controls and routes within an add-on and you just install that. How did the routes and stuff merge with your own routes? I haven't looked at myself, but in Ember admin, in your router, it gives you a function to call and then you give options to basically where to mount it. I don't think there's been conventions over that, so that's probably something that's developing, but it seems fairly straightforward. And then with the Liquid Fire, you said that's a separate Ember app, so is that separate from your Ember app? Yeah, it's just the repository that the add-on is in. It's also an Ember app in itself. So the documentation site, when you go to liquidfire.com or whatever it is, is the add-on, but it's the Ember app within that. So when you run it in the context of your own Ember app? You're only taking add-on files. That's why they override where to fetch things from, because that would collide with their demo app, basically. To run in another, it just works if you reference it in the package JSON of the NPM definition. If you add it in dependencies, not dev dependencies, then that will be installed when you NPM install it. And if that's got an Ember add-on keyword, that just gets installed within your app as well. I don't know if there's a limit on how deep that goes, but certainly I haven't done it myself and what I've seen on ISE, people have done that kind of thing yet. Yeah, again, it's NPM, so you can just link it to a version. So in your package.json, tag it to a version. You can tag it to specific Git repositories and, obviously, tags and charges and things like that. Everything you can do with NPM, basically. So what hooks are there in the actual build? So would it be possible to do something, say, after the ES6 has been transpiled, but before it, does the development contaminate it? I'm not sure you can specify when it gets when. After everything gets when, there's a post-process hook, so you can guarantee that everything else has happened. We're not on the final tree, but I don't know of a way of inserting it in between two other add-ons or specific stages. It doesn't like ES6, so you get to run it after. After the transpiling has happened. But it's available. There may well be a way, because I know of JS Hints, there's the ES Next add-on, which means you can write ES6 classes and everything, and that gets transpiled to JS. And then I think JS Hint gets run on it, so there may well be a way of doing ordering and bottom-up, I'm not sure. Cool, okay, thank you.