ADDY OSMANI: Hi there.
My name is Addy Osmani.
I'm an engineer on the Yeoman team.
And today we're going to walk through creating a new web
application using Yeoman, a workflow comprised of tools
for improving your productivity and speed during
development.
Yeoman is comprised of three main tools--
Yo for application, Bower for front-end package management,
and Grunt for building your projects.
Let's dive right in to creating a new to do
application from scratch.
To get Yeoman installed, you'll need to
use Node and NPM.
Make sure you have recent versions of both available so
that everything works correctly.
So we're just going to run NPM install g, yo, and allow it to
go install its dependencies.
And we're now going to install an AngularJS Yeoman generator
for scaffolding out a new Angular app.
Now, you only need to do this once, so NPM install g
generator angular.
Fantastic.
Now, we can go run yo angular to begin scaffolding a new
application.
This will ask us a number of questions, such as do you want
to include Twitter Bootstrap?
I'm going to say yes.
It gives us options about whether we want to use Compass
and a few other angular resources.
What this process is now doing is fetching any dependencies
needed for our AngularJS workflow and scaffolding out
any files required for application.
Next, I'm going to preview what this looks like.
So I'm going to use Grunt server.
And this is now firing up a local server for me to preview
me application.
And there we go.
Because this project is using Live Reload, I can actually
make changes to my sources, and without me having to do
anything else, it'll refresh my browser for me, so I get
this real time view of what's going on inside my app.
Now, I'm going to go to my angular controller that was
scaffolded out.
And what I'm doing right now is I'm creating a
new array of todos--
so item one, item two, and item three.
And these are some simple todo items that'll be
reflected in my app.
I'm now going to go back to main.html.
And we're going to define a template for these todos.
My todos is going to be the title of this page.
And I'm going to start defining my
template, so new paragraph.
And I'm going to use NG repeat, which is an angular
directive for allowing me to basically repeat something for
different items in a collection.
So I've got repeat, todo, and todo, so for each todo in my
todos array.
And I'm now going to just declare a new input field.
And I'm using NG model which represents a new angular model
with two way binding.
As you can see, it's now reflecting the todos array
that we defined earlier inside my page.
Let's now add the ability to create some new todo items.
And I'm going to define a new form for this.
So let's go down.
Let's create a brand new form.
And I don't need the action on it.
But what I am going to do is that NG submit, which is
another angular interactive.
And I'm going to say, call add todo whenever
this form is submitted.
What we're now going to do is just add some divs for
styling, some div wrappers for styling, add
some classes on that.
And next, I'm going to add an input field referencing our
todo model.
So there we go.
And NG model equals todo.
Let's give it some constraints for the number of characters.
And we should also probably add a button just to say add
or something like that, so that when you've typed in some
text into your input field, we can just click on Add to add a
new todo item.
And there we go.
Awesome.
Let's now head back to main.js.
As you can see, there's a preview of our application
displaying the new field and the new button.
We're going to head back to main.js.
And here we're going to add in that todo
function to our scope.
So there we go-- add todo function.
And this is basically going to push new todo items to the
todo array every single time that you create a new todo
item from the UI.
There we go--
perfect.
So let's quickly test this out.
So let's say buy some more milk and add--
there we go.
It's working.
Learn AngularJS suite--
awesome.
So that all works great.
Next, let's look at the ability to remove todo items.
So I'm going to go and head back to my main.html file.
And we're going to add a button to our template, which
is basically an x.
And that's going to appear next to each to do item,
allowing you to remove it.
So here we've added another directive, NG click.
And it's basically referencing remove todo,
passing through a reference.
And, as you can see, the x now appears next to each item.
And we're going to head back to main.js and define our
remove todo function within our scope.
So scope.removetodo equals function.
And we're going to use the splice function which lets us
remove old elements from an array using an index.
And there we.
Index one--
perfect.
So let's try this out.
Buy some more milk.
We've added it and removed it.
And as you can see, this all works great.
So how about next we make our todo items sortable?
So let's refresh the page.
We're going to use the Bower package manager for this.
So what we want to do is use AngularUI, which is a
companion to the AngularJS project for UI components.
So first I'm going to list what packages I have locally
installed using Bower Lists.
And as you can see, we have a few of them
pre-installed for us.
And now want to check to see if AngularUI is actually
available via Bower.
So I'm just going to type in, Bower search AngularUI.
And as we can see, it's already up there.
So I can now just run Bower install, save, AngularUI.
And there it's gone and installed it.
So all we need to do now is just add some references to
the AngularUI stylesheet and script within our index file.
So components AngularUI build, AngularUI.css.
And let's add a reference to our script as well.
So script src equals components, Angular UI build,
angularUI.js--
fantastic.
And the last two dependencies we need are jQuery and jQuery
UI, which I'm going to just wire up using some references
to copies that are hosted on a CDN.
So there we go.
We've got jQuery 1.9.1, jQuery UI 1.10.2.
And I've now saved them in my index file.
So now that we have AngularUI installed, we can add a
reference to it in our app.js file.
So let's head on over to app.js.
And inside our angular module, we've just defined a new array
referencing UI.
So we're going back to our todos template.
And I'm adding a div wrapper around our todos with the UI
sortable property on there.
And refreshing--
and let's try this out.
Awesome.
So as you can see now, I'm able to sort my
different todo items.
And that's working on all new items.
Let's add in a new item and see if it works
on that one as well.
So buy some unicorns--
perfect.
As you can see, that's working great.
Now we can sort our todos, and that works fantastic.
So one thing you might notice is that when we refresh the
page, any todo items that we've created automatically
get reset, because they aren't being persisted.
Let's change that, so they get saved to
local storage instead.
This time we're going to install the angular local
storage package--
so Bower install.
There we go.
And now we're just going to wire it up
inside our index file.
So src equals components, angular local storage, angular
local storage.js.
There we go.
Now, going back to app.js, I need to add a reference to
local storage modules.
So inside the same array as earlier, local storage module.
And there we go.
And inside our main.js file we need to add a local reference
to local storage module.
So we're going to call it local store service, just so
we can access it inside our controller.
I'm going to comment out the todos that I had earlier, the
ones that I hard coded in.
And we're going to add some code that's, first of all,
going to read any existing todo items from local storage.
Under the todo name space, we're going to then split them
up based on a new line character so that we can get
back anything want into our array.
So todosInStore.split based on new line.
And then we're just going to register a watch expression,
so that we can keep our todo items name space updated with
a joined version of our todos.
So watch, function, and localStorageService.add todos,
scope.todos.join.
New line.
Save and test that out.
So now I'm going to create some new todo items.
So learn, AngularJS, add buy some unicorns, add learn to
skateboard.
And now let's refresh the page.
They're still there.
Let's open up the Chrome dev tools just to check if these
are being stored.
So as you can see, they're actually being persisted to
local storage, which is fantastic.
So now we have an application that works.
The next thing we want to do is write some
unit tests for it.
So let's comment out the code that we just added and reset
back to the static ones that we had earlier just to make it
easier to test for a moment.
So I've got my original todos array.
And now I'm going to head on over to my Karma unit tests
that were scaffolded out for me when I ran yo angular.
So I'm heading to main.js, and here's some boilerplate code
for my unit tests.
And we already have an assertion here that says it
should expect a list of awesome things in the scope.
Now, awesome things, if you remember, is that array we
initially had, which just defined a few items to display
on the [? lo lo ?]
boilerplate page.
Let's replace it with todos, as we've now got a todos array
inside our scope.
And as you can see, all I can here is change this to check
on the todo items that I find inside my scope.
And I want to check that the length is equal to three.
Let's save that.
Let's run Grunt test.
What this is now going to do is go and fire off Karma,
which is going to run our unit test.
We've got a spec runner running in the
background for us now.
And that's really it.
You can check to make sure that your unit tests are
running correctly.
Now, the next thing you'll probably want to do is build a
production ready version of your application linking to
your code, minifying and concatentating your assets,
and handling any abstractions you might be using, like
CoffeeScript, and creating an optimized build that you can
push to production.
So we can do this just by running the Grunt command.
And there we go.
It's ready.
Now, the final thing you might want to be able to do is
deploy your application.
You can customize your Grunt project to deploy to pretty
much anywhere, whether it be Google App Engine
or something else.
But in this case, we're going to deploy to Heroku.
Now, I'm going to use another Yeoman generator to save me
some time here.
So I'm going to go back to the command line, and I'm going to
run NPM install generator Heroku.
You normally have to go through a number of steps to
push to Heroku, including using get
to handle this process.
But using this generator save us a lot of time.
As you can see, it's going and it's installing any of the
dependencies that it needs.
It should be done in just a sec.
I can now just clear my screen and run yo heroku.
Now, this is just going to generate me some configuration
that I can copy to my Grunt file for my Heroku deployment.
So it's going to ask me a question.
Do I want a separate Git repository in dist?
I'm going to say yes.
There we go.
There's our configuration.
Now, I just need to go and copy paste this into my Grunt
file under the copy task.
So there we go--
copying that over, back into my text editor.
Perfect.
And now I just push my dist directory, which contains the
production version of my application to Heroku.
And so let's CD into dist.
And I can run Heroku Apps Create.
And now I just need to push it to Heroku-- so get subtree
prefix dist, Heroku master.
Perfect, and now it's done.
Now here's a version of my application that I pushed to
Heroku earlier.
And that's it.
I created a new application.
I was able to use Yeoman to basically scaffold it out,
build it, test it, and I pushed it to Heroku, so I can
easily share it with other people.
Now, if you like what you saw with Grunt there are actually
hundreds of Grunt tasks available to help you achieve
lots of common development tasks at build time, including
compiling your CoffeeScript, or using something like
grunt-contrib-connect to hook up your application to some
middleware, like Express or PHP.
If you like what you saw with Bower, there's actually a
growing number of easily installable packages on the
Bower registry.
And the number of open source projects supporting it and
using it are growing weekly.
Bower is great for handling dependency management for you.
So if you want to easily update your dependencies, you
just run Bower Update, and it does it for you.
And Yeoman has a growing number of generators
available on NPM.
We actually have over 50 available at the moment.
And they're not just useful for kickstarting off brand new
applications.
Yeoman can be used to scaffold out little bits of
applications, as well.
So if you wanted to create a new Angular view or directive,
you could actually just use the same Angular scaffold that
I showed you earlier to create that at the command line.
We've got generators available for Backbone, Angular, Ember,
and a growing number of different frameworks.
So feel free to check out NPM if you'd like to get some more
of those generators installed.
And that's it.
If you'd like to learn more about Yeoman, please feel free
to check us out at yeoman.io.
Until next time, thanks, and goodbye.