Last updated: 31 Jul 2017.
Thank you for downloading the MEAN.JS boilerplate!

This simple documentation will cover the basics of developing your MEAN application.

Before you begin we recommend you read about the basic building blocks that assemble a MEAN.JS application:

MongoDB
Go through MongoDB Official Website and proceed to its Great Manual, which should help you understand NoSQL and MongoDB better.
Express
The best way to understand express is through its Official Website, particularly The Express Guide; you can also go through this StackOverflow Thread for more resources.
AngularJS
Angular's Official Website is a great starting point. You can also use Thinkster Popular Guide, and the Egghead Videos.
Node.js
Start by going through Node.js Official Website and this StackOverflow Thread, which should get you going with the Node.js platform in no time.
When you're done with those resources and feel you understand the basic principals continue to other sections.

Enjoy & keep us updated,
The MEAN.JS Team.

In this section you'll learn how to get started with a MEAN.JS application, install all the prerequisites, and initialize your application.

Prerequisites

Before you begin, you should make sure you have installed all these prerequisites on your development machine.


Git
Make sure you have Git installed in your system. OSX and Linux machines typically have this already installed. You can see if it is installed by typing:
$ git --version
Node.js & npm
Download & Install Node.js and the npm package manager, if you encounter any problems, you can also use this Github Gist to install Node.js.
MongoDB
Download & Install MongoDB, and make sure it's running on the default port (27017).
Bower
You're going to use the Bower Package Manager to manage your front-end packages, in order to install it make sure you've installed Node.js and npm, then install bower globally using npm:
$ npm install -g bower
Gulp
You're going to use the Gulp Task Runner to automate your development process. You may use Gulp for Live Reload, Linting, and SASS or LESS compilation. In order to install it make sure you've installed Node.js and npm, then install gulp globally using npm:
$ npm install -g gulp

Note: Your user might not have the permissions to install package globally, so use a super user or sudo.

Downloading MEAN.JS

There are several ways you can get the MEAN.JS boilerplate:

Cloning The GitHub Repository

You can also use Git to directly clone the MEAN.JS repository:

$ git clone https://github.com/meanjs/mean.git meanjs

This will clone the latest version of the MEAN.JS repository to a meanjs folder.

Downloading The Repository Zip File

Another way to use the MEAN.JS boilerplate is to download a zip copy of the latest MEAN.JS stable version. You can also do this using wget command:

$ wget https://github.com/meanjs/mean/archive/0.5.0.zip -O meanjs.zip; unzip meanjs.zip; rm meanjs.zip

Don't forget to rename mean-0.5.0 to your own project name.

Quick Install

Once you've installed all the prerequisites, you're just a few steps away from starting to develop you MEAN application.

The first thing you should do is install the Node.js dependencies. The boilerplate comes pre-bundled with a package.json file that contains the list of modules you need to start your application, to learn more about the modules installed visit the NPM & Package.json section.

To install Node.js dependencies you're going to use npm again, just run this in the command-line:

$ npm install

This command does a few things:
  • First it will install the dependencies needed for the application to run.
  • If you're running in a development environment, it will then also install development dependencies needed for testing and running your application.
  • Finally, when the install process is over, npm will initiate a bower installcommand to install all the front-end modules needed for the application.

Running Your Application with Gulp

After the install process is over, you'll be able to run your application using Gulp, just run gulp default task:

$ gulp
Your application should run on the 3000 port so in your browser just go to http://localhost:3000.

That's it! your application should be running by now, to proceed with your development check the other sections in this documentation.
If you encounter any problem try the Troubleshooting section.

During the installation process you may encounter some problems, so what can you do?

Check Node.js and npm Versions

The rapid advancements in JavaScript modules can sometimes cause version issues with the MEAN's dependencies. We try to keep up with the stable versions, and make sure the modules versions are compatible with those versions. We can't control the pre-installed platforms versions, so make sure you didn't install unsupported versions of Node.js and MongoDB.

MongoDB
MongoDB version 2.4.x is supported.
Node.js
Node version 0.12.x is supported.
npm
npm version 2.0.x is supported.

Update npm, Bower, or Gulp

You may find there is a weird error during install like npm's Error: ENOENT, usually updating those tools to the latest version solves the issue.

Updating npm (Unix/Linux)
To update npm just run this command in the command-line:
$ npm update -g npm
Updating npm (Windows)

There is a known issue with npm 1.x which is installed by default with the latest version of NodeJS. If you experience file locks during the "npm install" step, please refer here.

Updating Bower
To update bower just run this command in the command-line:
$ npm update -g bower
Updating Gulp
To update gulp just run this command in the command-line:
$ npm update -g gulp

Cleaning npm and Bower cache

Both npm and Bower uses a caching system that caches the packages you already installed. Often cleaning npm & Bower's cache can solve some of the issues you encounter during the installation process.

Cleaning npm's cache
To clean npm's cache just run this command in the command-line:
$ npm cache clean
Cleaning Bower's cache
To clean bower's cache just run this command in the command-line:
$ bower cache clean

Common Issues

There are some common errors while installing mean:

Node is running but AngularJS application won't load
Check to see all your front-end packages were installed. Bower package manager is used to install the front-end package and it will need a .bowerrc file to install the packages in the right location.
Bower should install the packages in the public/lib folder, so if this folder or some of its sub-folders doesn't exist, run:
$ bower update
This will install the missing packages.
Error: failed to connect to [localhost:27017]
If you use a local MongoDB check to see if its running. In case you use an external service verify the URI in the configuration files.

Sometimes it can be a local issue or something that we didn't cover, in case you have any further questions please contact us via the community page.

Common node-sass, and gulp-sass Issue

Another common error for applications using SASS revolves around node-sass and gulp-sass. The error may occur during npm install or when starting the server.

Error during install about node-sass, or gulp-sass
First uninstall the project and global gulp-sass modules.
$ npm uninstall gulp-sass
$ npm uninstall -g gulp-sass
Next uninstall the global node-sass module.
$ npm uninstall -g node-sass
Install the global node-sass first. Then install the gulp-sass module at the local project level.
$ npm install -g node-sass
$ npm install gulp-sass
Now try the npm install again from the project folder.
$ npm install
If your npm install still fails at this point. Repeat the above steps but use npm rebuild -g after the global node-sass install, but before installing the project gulp sass modules.
$ npm rebuild -g
As suggested above, you can also try npm update.
$ npm update -g

The folder structure of your MEANJS application is shown in the following diagram:

MEANJS Folder Structure

The application root folder is shown here with the name <project-home> but yours will be named whatever you like depending on how you decide to identify your own application. Below is an explanation of what goes where and why.

<project-home>

This is the base of your application and holds the following:

  • Application configuration files;
  • Hidden configuration files;
  • A set of files used to build and start your application; and last but not least...
  • The four main folders containing various code modules and libraries.

config

The config folder is where you house all the variable runtime configuration settings used by your application as well as a set of application helper functions. The following sub-folders are present within config...

config/assets

This section contains your asset management framework. When your MEANJS application is running, there will be a set of assets used to deliver functionality to your users. Assets in this context consist of files such images, cascading style sheets (css), JavaScript (js) and views (i.e. html templates).

Additionally, there may be variations on individual specific assets used depending on which environment your application is running in (i.e. dev, test, prod). The essential role of this asset framework is to tell the application which asset files it needs to know about and where it can find them.

config/env

This section holds the files that provide configuration settings for various system environments (i.e. local, dev, test, prod) supported by your MEANJS application.

config/lib

The lib section is home to various helper functions, i.e. 'library' modules, used by your MEANJS application. It includes components that provide support such as bootstrapping the application, establishing express capabilities, logging, database interaction, multi-part uploads, seeding new user accounts, and establishing socket connections.

modules

The modules folder is home to the main front-end AngularJS logic for the application. As you create various front-end capabilities and features in the application, each one will reside within this folder as a standalone module. As described in the AngularJS Developer Guide, "you can think of a module as a container for the different parts of your app".

While we provide a few out of the box, you will be responsible for creating your own modules as you use MEANJS to develop your own application. Sub-directories within each modules folder should generally have the following structure...

modules/*/client

Client-side code and associated files relating to the specific module.

modules/*/server

Server-side code and associated files relating to the specific module.

modules/*/tests

Code and associated files used to verify/validate other code related to the module.

public

This folder contains all the static front-end files used by the app to be served out. It includes elements built from your application's source as well as third-party external libraries required by your application.

As you proceed in building your application, you will see two sub-folders within the public folder...

public/lib

External libraries used by your application and introduced by Bower will be placed here.

public/dist

Final application files that you build ready for use will be placed here. For example, this will be the destination for minified scripts for use in production.

scripts

This folder is home to various helper scripts used during development, administration and operation of your application.

Powering every robust web application is a web framework. The MEAN.JS boilerplate uses Express as its web framework. Express is described as "a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications... Express provides a thin layer of fundamental web application features".

The home for Express configuration in MEAN.JS is in the config/lib/express.js file. In this section, we describe how we configure and implement Express in MEAN.JS.

Exposing Config Properties

app.locals

An Express application has the ability to set custom properties in the app.locals object, which MEAN.JS does. Once set, app.locals properties persist throughout the life of the application. This is useful when you want a property to be globally accessible for all clients, i.e. users/sessions, connecting to the server.

res.locals

Our Express application also has the ability to store response local variables, i.e. res.locals, scoped to the request. MEAN.JS makes use of this functionality. A res object in Express represents the HTTP response that the app sends when it gets a HTTP request. As per the API documentation, using res.locals is useful for exposing request-level information.

Routing

One of the bonuses of using Express is that we get a routing framework out of the box. In the context of MEAN.JS, routing refers to the way the app handles the combination of URL and request method that come in via requests from the client.

When a request comes in, the URL defines several things including the path to the requested resource, possible queries and a possible hash/fragment.

URL parts

In addition to the URL of the request, there is the request method. This is the desired action to be performed on the resource specified by the URL. The most commonly recognisable four request methods being GET, POST, PUT and DELETE.

The combination of the URL and the method that comes in via each request essentially forms a route. In MEAN.JS we define how we handle each route that comes in. To do this, we utilise Express' simple and well defined approach to routing. As described in the basic routing guide on the Express website, a route definition in Express has the following structure:

app.METHOD(PATH, HANDLER)

Where:

  • app is an instance of Express;
  • METHOD is an HTTP request method;
  • PATH is a path on the server; and
  • HANDLER is the function executed when the route is matched.

Middleware

Another of the primary goals of Express is to provide a middleware framework for web apps. The creators of Express provide a simple description, stating “middleware are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle.

Note, the order in which you define your middleware in your code matters and this is reflected in MEAN.JS. When your app starts up, the order in which middleware functions are loaded determines the order in which they’ll be executed.

In addition to defining a few of its own middleware functions, MEAN.JS loads the following third-party middleware inside our Express config file:

We use Mocha to test the server side logic. Mocha tests are asynchronous, easy to maintain, and uses a readable BDD syntax.

Assertions

Mocha needs an external assertion library to predicate the result of each test, in this case Should.js is being used. Should is an expressive library aiming to simplify tests and be readable. It extends the Object.prototype with a single non-enumerable getter that allows you to express how that object should behave.

Test Files

Each entity have its own test file located inside their respective module server tests folder. Ex.: modules/core/tests/server

Writing Tests

There are a few common steps we use to test an entity:

  1. In the beforeEach or before functions take care of prerequisites and create the objects you are about to use in your tests.
  2. For each test start with a describe function to indicate which method is being tested.
  3. Next, add your scenario tests using the it function.
  4. In the it function run the tests functionality and use should to assert what the end result should be.
  5. Finally use after or afterEach functions to finalize your tests and clear the test database.

Passport is an authentication middleware, which allows you to implement many authentication methods in your Express application.

Passport utilizes a modular approach that uses authentication strategies modules, offering a simple, configurable authentication solutions.

This boilerplate comes pre-bundled with 7 authentication mechanisms implemented in the config/passport.js file:

Local
The Local Strategy is used to authenticate users via username and password.
Facebook
The Facebook Strategy is used to authenticate users via their Facebook account.
Github
The Github Strategy is used to authenticate users via their Github account.
Google
The Google Strategy is used to authenticate users via their Google account.
Linkedin
The Linkedin Strategy is used to authenticate users via their Linkedin account.
PayPal
The PayPal Strategy is used to authenticate users via their PayPal account.
Twitter
The Twitter Strategy is used to authenticate users via their Twitter account.

To understand Passport better we recommend that you visit the Guide Section in the official website.

MEAN.JS has an AngularJS service that helps you manage your application menus. The menu service has several methods:

Menus.getMenu(menuId)
Returns a menu object identified by the menuId argument.
var menu = Menus.getMenu('myMenu');
Menus.addMenu(menuId, [options])
Creates a new menu object, which will be identified by the menuId argument. Includes the following arguments:
  • menuId (Required) - Indicates the menu identifier for future reference.
  • options (Optional; Default: {}) - Indicates the options object to initialize the menu with. Possible options include:
    • items (Default: []) - An array of menu items to initialize the menu with.
    • roles (Default: ['user, admin']) - An array indicating the roles that are allowed to view this menu.
Menus.addMenu('myMenu', {roles:'*'});
Menus.removeMenu(menuId)
Removes a menu identified by the menuId argument.
Menus.removeMenu('myMenu');
Menus.addMenuItem(menuId, [options])
Creates a new menu item object. This method also include couple of arguments:
  • menuId (Required) - Indicates the menu identifier.
  • options (Optional; Default: {}) - Indicates the options object to initialize the menu item with. Possible options include:
    • title (Optional; Default: '') - A String title for the menu item.
    • state (Optional; Default: '') - The UIRoute value, which is used to define the URL scheme where this menu item is marked as active.
    • type (Optional; Default: 'item') - This can either be 'item' or 'dropdown'.
    • class (Optional; Default: undefined) - CSS class(es) to apply to the menu list item (li) that is created.
    • roles (Optional; Default: menu.roles) - An array indicating the roles that are allowed to view this menu item.
    • position (Optional; Default: 0) - Specify the order of appearance.
Menus.addMenuItem('topbar', {title: 'Menu Item', state: 'menuitemstate'});
Menus.removeMenuItem(menuId, menuItemState)
Removes an existing menu with the provided menu identifier. This method also include couple of arguments:
  • menuId (Required) - Indicates the menu identifier.
  • menuItemState (Required) - Indicates the menu item state that should be removed.
Menus.removeMenuItem('topbar', 'menuitemstate');
Menus.addSubMenuItem(menuId, parentItemState, [options])
Adds a submenu item to an existing item object. This method also include couple of arguments:
  • menuId (Required) - Indicates the menu identifier.
  • parentItemState (Required) - Indicates the parent menu item state.
  • options (Optional; Default: {}) - Indicates the options object to initialize the sub menu item with. Possible options include:
    • title (Optional; Default: '') - A String title for the menu item.
    • state (Optional; Default: '') - The UIRoute value, which is used to define the URL scheme where this menu item is marked as active.
    • roles (Optional; Default: parent.roles) - An array indicating the roles that are allowed to view this menu item.
    • position (Optional; Default: 0) - Specify the order of appearance.
Menus.addSubMenuItem('topbar', 'dropdown1state', {title: 'Sub Menu Item', state: 'submenuitemstate'});
Menus.removeSubMenuItem(menuId, submenuItemState)
Removes an existing menu with the provided menu identifier. This method also include couple of arguments:
  • menuId (Required) - Indicates the menu identifier.
  • submenuItemState (Required) - Indicates the sub menu item state that should be removed.
Menus.removeSubMenuItem('topbar', 'submenuitemstate');

Using the Menus service is usually done in a configuration sections of your application modules. A simple configuration would look like this:

angular.module('example').run(['Menus',
  function(Menus) {
    Menus.addMenuItem('topbar', {title: 'Example', state: 'example'});
    
    Menus.addMenuItem('topbar', {title: 'Example Dropdown', state: 'exampledropdown', type: 'dropdown'});
    Menus.addSubMenuItem('topbar', 'exampledropdown', {title: 'Example Sub Item', state: 'examplesubitem'});
  }
]);