 country of New Jersey. And I've been having a super great time here so far. Hope everyone else is as well. And I definitely hope I get to meet some more of you before the end of the conference. In the case that I don't, you can always find me on Twitter or GitHub at Britney Storos. And I'll also be tweeting out a link to my slides as soon as I'm done up here. So I work on the apps engineering team at Mozilla and one thing that we've been working on a lot is creating Firefox OS applications with Ember CLI. And I know we've all heard a little bit about Ember CLI so far during the course of this conference, which is Ember CLI is everyone's favorite command line tool for creating Ember applications really quickly and keeping them super organized. Before Ember CLI came along, there's a huge void in the tool set for JavaScript developers. There are things like Rails for Ruby apps and we were just really missing this core piece of our tool chain when we were developing our JavaScript applications. So a couple of months back, my team at Mozilla was actually trying to fill this void by creating our own command line tool. And it was cute. It was called Rec Room. And it definitely catered towards Firefox OS applications. You could scaffold any kind of applications with it but we really wanted to focus and cater towards Firefox OS developers as well. And as we were building this, I would come across some features that I wanted to implement and I would run into a problem or I would struggle through creating some sort of feature and I would find myself creeping on the Ember CLI code base to see how they solved it. And when you find yourself doing that, when you catch yourself doing that often enough, it might be a sign that you're building a tool that already exists. And maybe you should stop. So we did. And we decided to leverage Ember CLI instead. But the problem now was that Ember CLI didn't care about Firefox OS. We had this custom environment that we wanted to build for, that we wanted other developers to be able to build for. And Ember CLI didn't know anything about it. So we had to make Ember CLI care about our environment that we wanted to build for. And what exactly were our requirements? What were our needs? Firefox OS applications are actually just built using current standard web technologies. I actually couldn't have asked for a better person to speak after because Brian did a great job showing everybody how far the web has come and how great it is and how powerful you can do, how many powerful things you can do with it now. So Firefox OS applications are built completely with web technologies, which makes our requirements just a handful of modifications. The first one is that we need a manifest file. This is the same concept as the package JSON file. They are going to share a lot of the same properties and values you're probably very familiar with with this kind of concept. So we need Ember CLI to generate and validate this file for us. We also need some kind of UI components that kind of mimic the Firefox OS interface. We want our web apps to look and feel like they belong in Firefox OS. And we wanted a way to publish to the Firefox marketplace. So those were all of the requirements that we had. And each of these examples is a great use case for creating an Ember CLI add-on. And Ember CLI add-ons are the way that you extend the core functionality of Ember CLI. They're basically just NPM packages, so they follow all the standard NPM conventions that you're already familiar with. They'll have a package JSON file that will point to an index file as its entry point. So that's where you'll be able to add all of your custom logic and really modify the way that Ember CLI works for you. And they're super easy to create and install. In order to create one, you can just run Ember add-on, name of your add-on. And then to install one within an existing Ember CLI project, you can run Ember install add-on, and then the name of the add-on that you want to install. Okay? So the first requirement that we had, we wanted to create... Sorry, one second. I'm going to back up. And we're actually going to use an application to demo a couple things with this. So I have an application, an Ember CLI application, running here just on the desktop. It's super simple. It just shows you your local time. And then you also have the ability to select different time zones to display and compare against the local time. So you'll always know what time it is in any given country. I don't have New Jersey in there yet, but I will put that up at the top of the list as soon as I'm done here. Okay? So we're going to kind of walk through creating an add-on. What would an add-on look like that turns this application into a Firefox OS application? And if we think about our first requirement that we had, we wanted to create a manifest file. So we need Ember CLI to generate this file for us. And we also mentioned that it's going to share some common values with the package.json file. So not only do we want to create this file, we want to keep it in sync with our package.json so that we don't have to have our developers updating the same values in two different places, right? So we want Ember CLI to do that. We're going to create blueprints to do this. Blueprints are basically just rules for generating common code and file structures. Ember CLI has a lot of these built in by default, and you can also add your own with a symbol command, Ember generate blueprint, and the name of your blueprint. So in the context of an add-on, when we create a blueprint, there's a concept of a default blueprint for add-ons. And what this is going to do, if we name our blueprint the same as our add-on, it's going to tell Ember CLI to install whatever files we specify as soon as the user installs our add-on. So if we go to the terminal really quick, I stubbed out a practice add-on that has some of this stuff implemented already. And let's say we ran our Ember generate blueprint command. This is going to generate some files and folders for us. See if you guys can see this? So if we run that blueprint command, we have this folder here called blueprints, and underneath it we have a blueprint called Ember CLI FXOS, and that's also the name of our add-on. Within here we have an index file where we'll be able to add some custom logic to the blueprint and modify the way that it works. And then we also have this files directory. And what this files directory does is we, within it we want to kind of mimic the directory of the consuming application. So if we want to create a manifest file in the public directory of the consuming application, we're going to create a manifest file in a public directory in this files directory. If we wanted to create a file in the config folder, we would create a config folder here, and we would put the manifest file in there. So what Ember CLI is going to do when it installs this blueprint is it's going to kind of merge these trees, the files from your consuming application with whatever you specify in your blueprints. So here we have our manifest file stubbed out with some of the default values, some of the required mandatory properties, and then you'll also notice some of these values have, are prefixed with out signs. And what we're going to do with those is replace them with package JSON values so that our developers don't even have to touch those, they don't have to think about them at all. So we have our blueprint set up in our add-on, and we have our application running, our Ember CLI application running. So I've already installed the add-on in this application that I'm going to be working in, but for the sake of demoing how this manifest gets generated, we could run ember generate ember CLI FXOS, and we should be able to see there that it created public manifest.web app. Is everyone able to read this code? Is that, yes? Okay. So let's just open this in our text editor real quick, and we can see in our directory we have public, and then there's our manifest folder, there's our manifest file. So it got copied over into our public directory just as we expected. So now how do we implement the part where we want to replace these variables with package JSON values? If we were to run ember build right now, this manifest file would get copied into our dist directory as is, and obviously these variables don't mean much. Version number is not a version number, and app name is not an app name. So let's take a look at the logic for implementing that. Okay. As I mentioned, in your add-ons, you're going to have your package JSON file point to an index file, that's your entry point. This is where you have all your custom logic for your add-on and how you're going to modify ember CLI's behavior. And from this index file, ember CLI provides us with some basic hooks that we can play into so that we can modify things at certain points in the build process, or we can add different properties and values to our application. So one hook that's available to us is called post-process tree, and it's a little bit obscure, or it sounds a little bit obscure, but what happens here is this hook is going to run every time you run ember build. It runs towards the end of the build process. When you have access to the trees that you can modify right before they go into the distribution directory. So we're going to say whenever we run ember build, we want to take our manifest from the public directory and also grab the values from our package JSON which are available within this method at this project package, and we're going to replace them. So I've already required in a function called sync manifest. We're not going to go over the logic for that, but the logic in that function is what is going to do the replacement for us. I just wanted to show you guys the hook and how this winds up affecting the way that ember runs its build command. So if we go back to our application and we run ember build, we should see in our disk directory a manifest file, and now we see that the version number was updated, the name of our application was updated, and the description was updated. All of these values were pulled from our package JSON at build time so that the developers never have to touch this manifest file. They never have to know that it even exists. Okay? So the next requirement that we had was UI components, and we want developers to be able to create applications that look and feel like they belong in Firefox OS, like they're native applications. We want them to mimic that. The interface layer of Firefox OS is called Gaia, and there's a repo with a bunch of different Gaia components. They have tabs and switches and menus galore, but it's very much a work in progress, so this is going to be a little bit of a contrived example. But say we wanted to create a tabs component, which would be available as a power package, Gaia components slash Gaia tabs. And creating a component off of this is a two-step process. You have two main responsibilities when you're creating a component. The first is to include your dependencies and actually create your add-on. So we want to include this power package for our Gaia tabs, and then we also want to write any kind of set up logic or teardown logic for our add-on. The second responsibility is making sure that both of these things, the dependencies and your add-on, are available to the consuming application. And this is the part that kind of muddies down creating components. It's not difficult, but there's a lot of different steps, and it's easy to miss something or it's easy to forget to do a particular one of them. So we're going to walk through an example really quickly. Don't worry if it's a little tough to follow, I'll circle back and review all the steps that we went over before I move on. So we're in our add-on right now, and say we already did our Bower install of the Gaia tabs component. If we look in our Bower components, I have this folder structure right here, Gaia tabs, so we have that available in our add-on, because our component is going to depend on this Bower package. But it's not enough that our add-on has this Bower package. We need to tell the consuming application that it's going to need this Bower package, too. So when we were creating our blueprint file, I mentioned that there's an index file there where we could add some custom logic. And I also mentioned that this blueprint gets generated automatically after you install your add-on to an application. So this would be a great time to tell your application, hey, you're going to need this Bower package, too. You might as well install it now. So just like in our index file of our add-on, we also have a couple different hooks for blueprints. One of which is after install. And what we can do here in this after install hook is just return this built-in method, this add Bower package to add GaiaTabs. And that will tell our consuming application you need to do a Bower install of this package, of these GaiaTabs. And our application will do that. Now that makes the Bower package available for our consuming application, but we still have the JavaScript file and the CSS file from this Bower package that we need to include into our application. We need to not just make the Bower package available for use, we need to actually use it. So in the index.js file of our add-on, we have another hook here that was sitting here earlier and I didn't mention anything about it, but this included hook is another one of the hooks that runs during the Ember build process. And this is a great place to import any of the dependencies that you need for your consuming application. So one of the things we can do here is run an app import and then we're going to grab the directories, the paths of our JavaScript file and the CSS file that we need. That has never happened to me before. That's funny. Okay. So we have our dependencies. We took the Bower package in our add-on and we also gave our consuming application access to this Bower package. Now we still have to actually create our add-on. So what we're going to do here is we want an add-on directory with a corresponding components directory underneath it and we're going to have a file named after our component that we're creating. So we're creating GaiaTabs. And this is where you can, this is the meat of your component. This is where you can define your tag name or set up attribute bindings and do any set up or tear down logic. And now we have a component in our add-on, but just like we did with our dependencies, we have to tell our consuming application about it. We have to tell the application that wants to use this that it's available for the application to use. So the way we want to do that is by creating an app directory. And under the app directory we're going to have another components directory and another file called GaiaTabs. But literally all this file is going to do is import our component that we just created and export it back out so that our consuming application knows that it exists. And then finally we need a template for our component. So again under the app directory we have a templates folder with components underneath and a handlebars file that simply defines the template for our GaiaTabs. So in our application that's using this add-on, that's using this component, if we look at our application template file, we see I have this already implemented in here, so I have GaiaTabs and then I'm setting the menu tabs that we need to populate our tabs component and that's what's controlling the clock and the time zones links back and forth. So that was a decent amount of information and like I said I promised I would review what we just did because it's a little confusing, there are a lot of files involved. What do we do with dependencies? We Bower installed our GaiaTabs dependency into our add-on. We told our consuming application that it needs that Bower dependency as well. And then we actually included the dependency files so that they can get processed at build time. The component logic, we created our component, we did our setup logic, we did our teardown logic, we gave it a name, we created this component in our add-on. We exported the component to the consuming application so that the application can actually use it. And we defined a component template. So there are six steps basically in creating a component. This is one of those things that hopefully in the future it will get a little bit easier to do. Even if it's still a little hard to follow right now, I promise the documentation on Ember CLI's website goes through every single one of these steps so you just have to not miss one thing. And there's a lot of good example add-ons out there that you can use to follow and you can learn from to create components. Okay, so we had one more or two more things on our to-do list, validation and publishing. We wanted to validate that manifest file and we also want to be able to publish to the marketplace. And unlike our syncing of our manifest file with our package JSON file, we want to have more control over when these things are run. We don't want to be publishing to the marketplace every time we build our application. So this makes them really good candidates for being commands, for creating commands. So just like you might run Ember New or Ember Serve, we want to be able to run something like Ember FXOS Validate or FXOS Publish. So let's look at what a command looks like in Ember Ember CLI. So I have a lib directory with a commands directory underneath and an index file here. And this index file is just exporting an object where the keys are the names of your commands and the values are the actual commands. And if we look at this Validate file with our Validate command, we can kind of see the basic structure of what a command should look like. It should be what you type in the terminal to run the command. It can have aliases in case it's super long and you want some shortcuts. It should have a description and we should be able to tell that it works inside of the project, inside of an Ember CLI project. And it also has a run method and this is where all the magic is going to happen. This is where we're going to actually write our validation logic. I've already imported a Validate file. We're going to get the code for that because it's not relevant exactly to you guys. So we're just going to return this. We're going to validate our manifest file and that's what's going to happen when we run our Validate command. But Ember CLI doesn't know that we put these commands in here. It doesn't know about these yet so we need to tell it that these commands exist and that the application can use them. If we go back to our index.js that Ember CLI has built in for us to utilize. This one is a lot simpler to understand. It's just included commands. And all I'm going to do there is return my object of commands. So I already required that in at the top of this file. And we're just going to return that object of the Validate command and the published command. And now if we go to our terminal and we try to run one of these from our application let's do Validate. We see that it validated our manifest for us. The validation passed. We have a warning message but we don't care about that right now. And we know that our command was there and it works. It's doing what it's supposed to do. Another way we could have told if this command was available to us is by running Ember help. And besides just running the core commands and information about Ember CLI what it's also going to do is list out information about the available commands from your add-ons. So that's a super helpful thing when you have add-ons that are incorporating commands. Your Ember help command will also list those. And we see that we have a Validate and a published command here. The published command I'm not going to go too much into. We're actually still editing this but I have it set up locally. One thing I just want to point out is another property of commands is that you can specify available options. So if you want to throw in a flag when you're running a command you can throw in one of these options. You can define a name type and set default values for these. And these options that get passed in are going to be available to you through this options hash in the run method. So when we want to run publish we want to publish to the developer marketplace, the development marketplace versus the production Firefox marketplace. We could pass in an environment option that says development. If we're ready to publish to production we could set environment to production and it would publish to the production marketplace. So I have my marketplace opened up here. I'm logged in. And if I click on my submissions I see that I don't have any applications right now. But if I run my publish command from my application I should get an app ID back. So we have app successfully created and we have an app ID to reference. And now if we look over at our marketplace we see that we have our application. So we have our application and we refresh. We should see our application time zone clock right there. So those were just a couple of different ways that you could use add-ons to extend the functionality of Ember CLI. There's a lot more use cases and there's a lot more examples out there. I encourage you to look at the documentation because there's a lot of things that you can do with Ember CLI that you can follow by example. You can really get Ember CLI to do almost anything that you want. It's kind of a push over like that. But it's a really great tool so definitely take a look at it if you haven't. Start working with it if you haven't. Also if you're interested in learning more about creating Firefox OS applications you can take a look at this add-on that we watched last week. It's a really great tool and it's a great tool to see in the app's channel. I don't believe I left time for questions but if you have any feel free to tweet at me or find me before the end of the day and I would be happy to talk more about this with you. Thank you.