We're going to take a tour through a popular MEAN stack boilerplate implementation and pay close attention to how each of the parts fit together and why the boilerplate maintainers decided to structure their app the way they did.
We are going to be very through with the code walkthrough, going line-by-line and following the app's logic beginning to end, inside and out.
You, dear reader, are my rubber duckie.
- Basic understanding of Node and Express
- Some familiarity with MongoDB and Mongoose
- Rudimentary knowledge of AngularJS
Learn Node by following this guide by the same guy. Concentrate your efforts on understanding modules, the express framework, and the concept of middleware.
Get up to speed with Mongo and CRUD operations at Mongo's official education site. The first two weeks of the MongoDB for Node.js Developers (M101JS) courseware are a great start. Even though they use the official Mongo driver in Node, you'll be able to apply the knowledge to Mongoose.
Introduce yourself to Mongoose with their official quick start.
Get acquainted with AngularJS by running through their official tutorial beginning to end.
And here is a good introduction to how they all fit together as the MEAN stack.
The more background you have with these technologies, the more the boilerplate will seem like an enlightened ordering of useful tools and less like a tangled mess of folders, files, and code.
Even if you've read plenty of theory and done exercises with each of the technologies in MEAN independently but haven't put together a non-trivial app yet, it's possible (and probably likely, if you're anything like me) that when you sit down to build an app you will have no idea where to start.
This blank slate is very intimidating! You know you need a sensible structure if you are building a non-trivial app and the structure you choose should be based on current best practices, of course - but since best practices come with experience and we don't have experience building professional applications with the stack it's likely we'll just be guessing and very possibly our guesses will be misguided or rationalized by faulty assumptions.
Fortunately, there exists quality boilerplate for MEAN apps that we can use and reuse without having to 'create the universe' first every time we start a new project.
I ultimately decided to tour the angular-fullstack Yeoman generator over the mean.io boilerplate for two reasons:
- It includes thorough optimization tools for preparing a project for production, preconfigured with sensible defaults
- It doesn't require any additional configuration to see changes to your project happen live (that is, changes to server files will restart the node instance when you save them, and changes to frontend files will reload in your web browser when you save them)
The Linnovate mean.io boilerplate can do both of these things as well (and the other yeoman MEAN templates as well) but not without additional configuration.
The purpose of this exercise is to explore the structure of a well organized app. Fussing around with grunt tasks is a distraction, and angular-fullstack is pretty much ready to go out of the box, so that is what we'll be using in the tour.
Setting Up Your Environment
You can replicate my development environment by following these instructions. I am using Ubuntu, so Mac and Windows users will have to modify this process somewhat.
Install node. I built node from the current source. If you're using Ubuntu, don't use the nodejs package from the official repository because it's old. I used
apt-get install build-essentialthen got the node source tarball. Unpack it, enter the directory you just unpacked it into and
makethen (as privileged user)
make install. Other options and more detailed instructions are available here.
Install MongoDB and get it running. I followed these instructions for my Ubuntu server.
Install yeoman globally. You may need to perform this command as a privileged user.
npm install -g yo
Install the angular-fullstack generator for yeoman globally. You may need to perform this command as a privileged user.
npm install -g generator-angular-fullstack
Make a new directory, enter it, and have yeoman generate the boilerplate for you.
Yeoman will ask you a few questions:
- No, I don't want to use Sass/Compass.
- Yes, I love Twitter Bootstrap.
- Press enter. Sure, we'll take the standard compliment of Angular modules.
- Yes, we want MongoDB with Mongoose.
- Yes, we want to use passport middleware to authorize users.
Yeoman will retrieve all the good stuff and put it where it belongs.
At this point, let's run what we have, to make sure everything works. Type
grunt serveand direct your browser to localhost:9000. You should see the ever-friendly Yeoman on a somewhat boring but functional welcome page.
Be patient if it doesn't load immediately. This is a development build and nothing is optimized or being cached at this point.
grunt serveinstead of
node server.js? Because grunt runs some helpful tools in the background that restart the node server if we alter certain server files, and make the browser reload the page when we alter certain frontend source files. This is very convenient when you want to see changes to your app reflected live or nearly live.
Kicking The Tires
This simple page has a lot going on, despite appearances.
First, look at the list under the Yeoman splash. It will probably include HTML5 Boilerplate, AngularJS, Karma, Express, and MongoDB + Mongoose (depending on your answers to Yeoman's questions when you ran the angular-fullstack generator). This list is dynamic: the node backend used mongoose to pull the items in the list out of a mongodb datastore, and delivered the list to angular on the frontend which used the objects in the array returned from the server to populate the list.
At the top of the page, hit 'settings' and notice it redirects you to the login view. Angular's router intercepted the 401 or 403 http response and sent you to the login view instead of displaying the 'forbidden' error.
Go ahead and login with
firstname.lastname@example.org as your email and
test as your password. When you login successfully, notice the Yeoman splash is now addressing you by your account's real name, "Test User." This is also a dynamic element Angular is filling in for us.
You can log out and create a new user and login as the new user if you please. Don't make an account with a password that you use for anything else - this sample app is being served over unencrypted http (as opposed to https) and your password will be transmitted in plaintext over the network (if you aren't serving the app locally).
Even though this app will let you make new users and save your changes to the test user's password, and even though the app will correctly alter the database to reflect these changes, it will all be erased when you quit the server process and start it again. This is because the app erases the database and repopulates it with its defaults every time you run the server.
In Part 2 we'll take a look at the file structure of the app and look inside server.js.