permalink

16

Full-Stack JavaScript With MEAN And Yeoman

2713158505_b854770190_b

Introduction

A trend proliferating amongst prototypers in the Angular community is full-stack JavaScript development via the MEAN stack.

The acronym stands for: (M)ongoDB – a noSQL document datastore which uses JSON-style documents to represent data, (E)xpress – a HTTP server framework on top of Node, (A)ngular – as you know, the JS framework offering declarative, two-way databinding for webapps and (N)ode – the platform built on V8’s runtime for easily building fast, scalable network applications.

Supporters of the stack claim the use of JavaScript all the way down increases productivity and it’s hard to dispute that this notion is pretty appealing. You get consistent models across the stack and consistent best practices in many cases too.

For example, in the case of Mongo – you can store documents in a JSON-like format (BSON – Binary JSON objects), author JSON queries in Express/Node and pass these JSON documents back to an Angular powered frontend. At a high-level, this is compelling and certainly make ease debugging when the objects in your database are identical to those your JS sees.

Note: There is little about the MEAN stack heavily coupled to Angular and a developer could substitute it for Backbone.js, Ember.js, Polymer or any other framework without losing the single-language stack advantages it offers.

Why MongoDB?

As mentioned, the choices in this stack, such as Mongo, enable the use of one language the whole way through. A fair discussion about the merits and critiques of the noSQL movement could easily fill several pages. We used MongoDB at scale back in my days at AOL and in the past two years I’ve seen an equivalent number of success and failure stories.

Critics of the MEAN stack sometimes point out that MongoDB may work well here for small-mid sized apps, but less so for large-scale applications (e.g 100′s of millions of users).  I would say it entirely depends on what you’re trying to do. SQL databases, being strongly typed in nature are great at enforcing a level of consistency, ensuring many kinds of bad data simply don’t get recorded in the first place.

NoSQL however is weakly typed, making very few attempts at data validation so that responsibility is placed back on the developer. They’re particularly well suited to storing data which is inconsistent (as a collary, this makes it great for prototyping when the data model rapidly changes).

The technical differences between SQL databases vs noSQL really come down to a tradeoff between performance and reliability. There may be cases where transactions against a data store simply won’t be modified once set. Mongo may be a good fit here. In other cases, you may have more complex transactions involved many separate logical units. There isn’t a simplistic data model in Mongo that gives you a level of atomicity and SQL may be a better fit here.

At the end of the day, you should figure out what your requirements are and choose the right tool for the right job – regardless of whether you opt for the M in MEAN or not.

Why Express?

Express is simply a utility belt for authoring webapps with Node. It offers simpler interfaces for creating request endpoints, cookie handling and so on than you would get out of the box with Node on its own. It also gives you functions for everything you may need to build your own web server. Some of the things Express does well are:

  • Enabling REST routes that are as simple as: app.get(/account/:id, function(req, res){ /* req.params('id') is available */ });
  • Easy templating through Jade or Mustache
  • Automated HTTP header handling: app.get('/', function(req,res){ res.json({object: 'foo'}); });
  • Support for Connect middleware for plugging in synchronous functions to handle different things with requests or responses, such as authentication
  • Utility functions for parsing the POST request body
  • XSS prevention tools
  • Graceful error handling

Without Express, you’re likely to end up authoring your own routing logic regardless but it also gives you access to plugins and a system that’s relatively extensible.

Boilerplate for MEAN stack

mean.io is a decent starting point for those looking for a boilerplate to get started with this stack.  It aims to solve common integration problems, is well-maintained, documents the additional packages that can be added to the stack and has inspired Yeoman generators such as generator-mean by James Cryer.

Yeoman and the MEAN stack

So, assuming that (a) we agree Mongo is suitable for at least prototyping in full-stack JS development and (b) we acknowledge that Angular may be superseded at some point in the future by another JavaScript framework, any tools that can help us get this stack setup quickly and easily could be quite useful.

This is where the Yeoman workflow comes in. It’s composed of three tools you’ve probably heard of:

  • Grunt is used to build, preview and test your project, thanks to help from tasks curated by the Yeoman team and grunt-contrib.

  • Bower is used for dependency management, so that you no longer have to manually download and manage your scripts, plugins or front-end packages.

  • Yo scaffolds out a new application, writing your Grunt configuration and pulling in relevant Grunt tasks and Bower dependencies that you might need for your build.

About a year ago, I and a number of others in the Yeoman community worked on a project called ExpressStack. The idea was simple – give you a set of tools for scaffolding out everything you need for full-stack JavaScript development. We’ve since deprecated ExpressStack but in it’s place, a number of similar projects have sprung up which are compatible with newer versions of Yeoman.

Let’s summarize them.

Note: You’ll need to have Yeoman installed (npm install -g yo) and one of the following generators, which you can install with npm install -g <generator-name>.

generator-angular-fullstack

An AngularJS generator, integrated with support for Express with optional MongoDB integration.

Features:

  •   Livereload of client and server files

  •   Express server integrated with grunt tasks

  •   Easy deployment workflow.

  •   Supports Jade templates

Write-up: http://tylerhenkel.com/creating-apps-with-angular-and-node-using-yeoman/

generator-meanstack

Another MEAN stack generator, compatible with grunt-express. Some of the things this does:

  • Replace connect with express on generator-angular.

  • Livereload on both backend and frontend files.

  • Bootstrap the application using an app_grunt.js file which refers to app.js with route definitions.

  • Use the same folder structure generated by the generator-angular with few modifications.

also see https://github.com/Grievoushead/generator-express-angular, which hasn’t been updated in a few months but does include sub-generators for a number of common tasks associated with MEAN stack development.

generator-mean-seed

A Yeoman generator for MEAN-seed, giving you a stack with Mongo, Express, Angular, Yeoman, Karma and Protractor for automated testing

generator-klei

Similar to the other generators, this also uses Mongoose and Stylus. Other features:

  •   A scalable directory structure (Todo list example included)

  •   A fully configured Gruntfile with livereload, linting, concatenation, minification etc.

  •   Automounting of API routes using exctrl

  •   No more editing of your html layout when adding scripts and stylesheets to your project, thanks to grunt-injector

  •   Frontend unit testing with Karma, Mocha and Chai

ultimate-seed-generator

A generator supporting the MEAN stack with a number of other batteries included, such as Passport and Browserify.

  •   AngularUI, Barbeque, Bootstrap

  •   Bower, Browserify, Express, Font Awesome

  •   Grunt, Handlebars, jQuery, JSHint, Karma/Mocha

  •   LESS/LESSHat, Livereload, Lodash/Underscore

  •   Modernizr, MongoDB/Mongoose, Passport

What should I use?

The obvious question after looking through the list of generators above is: “What should I use?”. I’ve ordered the list based on several factors, including how well the generator works with newer versions of Yeoman and how actively maintained the projects have been.

There’s clearly plenty of interest from the community in automated tooling for the MEAN stack, but what we really need is to get behind one or two generators that we can rally behind to improve, stabilize and scale out.

My hope is that this post will increase awareness of some of the current efforts in the Yeoman community to get out a great MEAN generator so we can solve this.

Is full-stack JavaScript practical for large production-level apps?

JavaScript all the way through is fantastic (at least for prototypes), however be careful not to shoehorn yourself into using it just because it’s claimed to be the holy grail. That said, we’re seeing an increase in the number of large-scale apps being built with similar stacks by the likes of Walmart and LinkedIn so more examples of this are almost certainly on the horizon.

It’s also worth noting that building a backend in Node is considerably more challenging than with other languages, such as Ruby, Python or Java. You have to manage memory leaks, keep in mind CPU-bound computations off the event loop and be very careful with exception handling unless you want to crash your entire app server. Many of these problems have already been solved with other platforms. That doesn’t mean Node can’t be used in production. It clearly can, but just requires further care.

Practically speaking, it’s going to be challenging for there to ever be a “one-size” fits all language or tool for developing for the web and some skepticism for the MEAN stack is to be expected.

There’s a huge amount of variance in front-end and back-end design patterns, principles and styles of doing things. If you find that PHP or Rails are more sensible options for your stack, use them, otherwise MEAN remains an option at least worthy of exploring at this time.

Other resources

With thanks to Pascal Hartig and Sindre Sorhus for their review.

16 Comments

  1. Hi Addy, thanks for a great article!

    I have a personal question: have you ever thought of porting your WordPress blog to a MEAN equivalent?

    • Very good question @vitaly, i would like to know that as well, if you have production site built on top of wordPress how would you port it to MEAN

  2. Hi,

    thanks for the write-up! From my experiments I can report that generator-klei worked as expected for me, despite the fact that it has the least stars on github.

    Cheers,
    Dirk

  3. How about RethinkDB?
    I use it with yeoman, angularjs build my idea.
    A newest one is the http://001.yaha.me that maybe a all JavaScript Full stack jobs there.
    it build on top of angularjs, nodejs(restify), and with ubuntu, nginx, apache (ya, apache is at HK, and the nginx,ubuntu is at linode Tokyo)

  4. Hi Addy,

    MEAN to me seems way too much _opinionated_, not only _opinionated_, in many cases it just won’t work.

    1. MongoDB is an awesome tool, I love it, but almost half of the time its not an option because of it’s own shortcomings.
    2. Express is a nice abstraction, for sure;
    But unless we are developing small apps with SOA in mind,
    it gets too dirty too soon. There is a reason that people use Rails more than Sinatra.
    3. I love Angular, but with lower skilled developers in team, we just can’t use it. Not to mention that personally I prefer Ember.
    4. Node isn’t 1.0 software :)

    I don’t know, people think I say no to MEAN because I’m a Rubyist,
    Nonetheless these are valid reasons.

    + I can’t get the analogy between weak or strong type systems and MongoDB or RDBMSes.
    To me, dynamic to static type system seems correct.

  5. excactly the topic i came across a few days ago, when i started a new angular app.

    decided to use the fullstack-generator, because i liked app-structure and documentation the most

  6. Great article Addy! I couldn’t agree with you more… would like to see the community rally behind a couple of MEAN stack generators.

  7. Also had success with generator-klei. Really good stuff. Had to force the mongoose version to 3.8.2 instead of ~3.8.1 because at time of writing npm is throwing an error when installing 3.8.3.

    Is anyone maintaining anything just like this, but for backbone? Just my personal preference for some projects…

  8. Thanks a lot for this article. I’m going to use MEAN in a few projects, so you helped me a lot with additional tools which I can use during my work. Thanks one more time :)

  9. Pingback: The Yeoman Monthly Digest #2 - InfoLogs

  10. Pingback: Full-Stack JavaScript With MEAN And Yeoman | Web Design Database

  11. Dude, in all seriousness, you are my personal web dev hero. I get so much from all your books/posts/articles which are always super informative and so damn well articulated! You have a great knack for bringing clarity to concepts that are so easily muddied with ambiguity. Thanks for being such an inspiration!
    -Dave

Leave a Reply

Required fields are marked *.