首页 > 代码库 > MEANJS DOC

MEANJS DOC

Overview

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.

 

Getting Started

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.

 

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
Grunt
You‘re going to use the Grunt Task Runner to automate your development process, in order to install it make sure you‘ve installed Node.js and npm, then install grunt globally using npm:
$ npm install -g grunt-cli

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:

Yo Generator

The recommended way would be to use the official Yo Generator which will generate the latest stable copy of the MEAN.JS boilerplate and supply multiple sub-generators to ease your daily development cycles.

Note: If you want to support git mergeupdates it would be better to use git clonefor your initial project creation, don‘t worry you‘d still be able use the generator.

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 from the master branch on github. You can also do this using wget command:

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

Don‘t forget to rename mean-master after your 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

After the install process is over, you‘ll be able to run your application using Grunt, just run grunt default task:

$ grunt

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.

 

Troubleshooting

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.10.x is supported.
npm
npm version 1.3.x is supported.

Update npm, Bower or Grunt

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
To update npm just run this command in the command-line:
$ npm update -g npm
Updating Bower
To update bower just run this command in the command-line:
$ npm update -g bower
Updating Grunt
To update grunt just run this command in the command-line:
$ npm update -g grunt-cli

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 AgnularJS 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 theconfiguration 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.

 

Folder Structure

The folder structure is quite self-explanatory, but here‘s an explanation on what goes where and why.

App

The server folder contains all the server files you use in your application, this is where you store your MVC server files.

  • controllers

    The controllers folder is where you store your Express application controllers, this is where you write your backend business logic.

    When to use: Whenever you want to add, change, or remove Express application controllers.

  • models

    Autoloaded 
    The models folder is where you store your Mongoose models, this is where you define your backend models.

    When to use: Whenever you want to add, change, or remove Mongoose models.

  • routes

    Autoloaded 
    The routes folder contains the Server routing configuration files, this is where you define your Express routes, in order to add routes to your module just add a .js file similar to the app/routes/articles.js file and MEAN will automatically load that these routes.

    When to use: Whenever you want to add, change, or remove a server route.

  • tests

    The tests folder is where you store your Mocha tests, this is how you test your backend business logic.

    When to use: Whenever you want to add, change, or remove Mocha tests.

  • views

    The views folder is where define your backend views. Since you‘ll use AngularJS, server templates are almost meaningless, but you still have to use a template engine to render the main pages, like the index and error pages. For more information visit the Backend Views section.

    When to use: Whenever you want to add, change, or remove backend views.

    • templates

      A backend templates folder, currently used for emails templates.

      When to use: Whenever you want to add, change, or remove backend templates.

Config

The config folder contains the files you need to configure your application.

  • env

    The env folder contains the configuration files loaded by the config.js file according to the current environment, for more information, please visit the Configuration section.

    When to use: Whenever you want to add, change, or remove your configuration properties.

  • strategies

    Autoloaded 
    The strategies folder contains the startegies configuration files loaded by the passport.js file.

    When to use: Whenever you want to add, change, or remove a Passport Strategy.

  • config.js

    The configuration loader that loads the right configuration from the env folder, for more information, please visit theConfiguration section.
  • express.js

    Express configuration file, it initializes & configures the Express application.

    When to use: Whenever you want to change the way Express is being initialized and configured.

  • init.js

    The initialization file that set up a few project related configuraiton.
  • passport.js

    Passport configuration file that initializes & configures the Passport‘s authentication strategies and middlewares from the strategies folder.

Public

The public folder contains all the static files you use in your application, this is where you store your front-end files.

  • dist

    The distribution folder is where you store your application compressed CSS and JavaScript assets. The uglify and cssmingrunt tasks are using this as their build target folder.
  • modules

    Autoloaded 
    The modules folder is where you store AngularJS application modules, to learn more about it visit the AngularJS Modulessection.

    When to use: Whenever you want to add, change, or remove AngularJS modules.

  • config.js

    AngularJS configuration module, it starts with two global properties and one method:
    applicationModuleName
    AngularJS is using a module system to bootstrap and application, in this case it will use this property as the main module name.
    applicationModuleVendorDependencies
    AngularJS allows to add dependencies to the main module forcing the application not to start if those dependencies aren‘t met. In this case we start with the basic AngularJS & Angular-UI dependencies, each third-party module you add to your application should be added to the applicationModuleVendorDependencies global property and AngularJS will load it automatically.
    registerModule
    This method is used to register a module as a new module and add it to the main module dependencies.

    Although you don‘t have to, it is highly recommended that you use registerModule method to reigster your module as a dependency for the main application module. To understand this better please visit the AngularJS Modules section.

    When to use: Whenever you want to add, change, or remove an AngularJS global configuration property.

  • application.js

    AngularJS main application file, it takes care of bootstrapping the application and attaching the right modules.

    When to use: Whenever you want to add, change, or remove a module in your AngularJS application.

Application Files

There are a few application files stored in root folder.

  • server.js

    Our main application file, where you initialize your Node.js application.
  • bower.json

    Bower definition file, where you configure the front-end components you want to use, for more information visit theBower section.

    When to use: Whenever you want to add, change, or remove front-end components.

  • Dockerfile

    Docker configuration file, where you configure all the commands you would normally execute manually in order to build a Docker image.

    When to use: Whenever you want to configure your Docker images.

  • fig.yml

    Docker development environment configuration file, where you configure your application environment with Docker .
  • gruntfile.js

    Grunt definition file is where you define your grant tasks, for more information visit the Grunt section.

    When to use: Whenever you want to add, change, or remove grunt tasks.

  • karma.conf.js

    Karma configuration file is where you configure your karma tests.

    When to use: Whenever you want to add, change, or remove front-end tests.

  • package.json

    npm definition file, where you configure the backend modules you want to use, for more information visit the NPMsection.

    When to use: Whenever you want to add, change, or remove backend modules.

  • Procfile

    Heroku process file, where you configure process you want to run on Heroku application Dyno.

Hidden Configuration Files

Notice that sometimes you copy your application folder‘s content and forget to copy the hidden files, this will cause issues and might break the application.

  • .bowerrc

    Bower configuration file, you use it to tell bower where to install your application components.
  • .csslintrc

    CSSLint configuration file, you use it to configure CSSLint special properties.

    When to use: Whenever you want to add, change, or remove CSSLint properties.

  • .editconfig

    EditorConfig configuration file, you use it to configure consistent coding styles between different editors and IDEs.
  • .gitignore

    Git ignore file, you use it to tell git what ignore in next commits. After installation the application generates a lot of code that you don‘t want to include in your repository, so this is where you tell git to ignore those files.

    When to use: Whenever you want to add, change, or remove files that are ignored by Git.

  • .jshintrc

    JSHint configuration file, you use it to configure JSHint special properties.

    When to use: Whenever you want to add, change, or remove JSHint properties.

  • .slugignore

    Heroku ignore file, you use it to tell Heroku slug compiler what ignore in next commits, which will prevent oversizing your final slug.

    When to use: Whenever you want to add, change, or remove files that are ignored by Heroku slug compiler.

  • .travis.yml

    Travis configuration file, you use it to tell Travis how you want your builds to be executed.

    When to use: Whenever you want to add, change, or remove TravisCI configuration options.

 

Configuration

So, you have your application running, but how do you configure it?

Environmental Configuration

The config folder is where you have all the files are organized in a specific structure, which starts with the config.jsfile.

The config file functions as loader for the configurations files placed in the config/env folder, it will load the right configuration file based on the NODE_ENV variable.

 

There are five default configuration files based on common development pattern:

config/env/all.js
This file will be loaded in all the environments, and contains the default properties that will be overwritten by any environment specified configuration.
config/env/development.js
This file will be loaded in a development environment, a property defined here will overwrite the one defined in the all.js file.
config/env/production.js
This file will be loaded in a production environment, a property defined here will overwrite the one defined in the all.js file.
config/env/test.js
This file will be loaded in a test environment, a property defined here will overwrite the one defined in the all.js file.
config/env/travis.js
This file will be loaded in the Travis CI testing environment, a property defined here will overwrite the one defined in the all.js file.

To run your application with a different environment configuration run the application like this:

$ NODE_ENV={The Environment Name} grunt

 

Configuration Properties

MEAN.JS comes with a default set of configuration properties you will most likely expand with your properties. Here‘s the review of all the required properties used in the configuration files:

config.db
This is the MongoDB connection string URI, when bootstrapped, the application will try to connect to the database using this URI, so make sure its the correct one in each environment.
config.port
The port used by the application, default is 3000, but as you can notice in the test.js config file, this can be changed.
config.app.title
This is title used as the HTML page title. Notice that it appears both in the all.js file and in all the non-production configuration files.
config.app.description
This is used in the HTML description META tag. Notice that it only appears in the all.js file and can be overwritten by an environment specific property.
config.app.keywords
This is used in the HTML keywords META tag. Notice that it only appears in the all.js file and can be overwritten by an environment specific property.

Assets Configuration

One of the major issues dealing with applications development is assets management. While bower helps you download and update the project front-end dependencies, you would still need to include the packages JavaScript files in several places including your main application page, Karma configuration file and the uglify grunt task. Furthermore, you may want to use different assets for different environments.

For this purpose we included the config.assets field in the environments configuration files. Using this configuration option allows you to organize all your assets inclusion in a single place. The config.assets field has a few properties:

config.assets.css
A list of glob patterns indicating the project css files.
config.assets.js
A list of glob patterns idicating the project JavaScript project files.
config.assets.tests
A list of glob patterns idicating the project Jasmine test files.
config.assets.lib

A list of glob patterns idicating the project packages files. We seperate those from other files so you could use CDN assets in your production configuration.

config.assets.lib.css
A list of glob patterns idicating the project packages CSS files.
config.assets.lib.js
A list of glob patterns idicating the project packages JavaScript files.

Note: You can also include CDN paths to load packages files directly from their official CDN.

Social Configuration Properties

The application will use the Passport module to offer users various login options.

MEAN.JS currently supports five social platforms: Facebook, Twitter, Google, Linkedin, and Github. You can also add other platforms using a passport-provider package and duplicating the samples logic.

To configure your social application oauth keys there‘s a property object for each platform:

config.app.{OAuth Provider}.clientID
Your application oauth id.
config.app.{OAuth Provider}.clientSecret
Your application oauth secret.
config.app.{OAuth Provider}.callbackURL
Your application oauth callback URL.

Remember to use different configuration for each environment especially your MongoDB URI and social platform OAuth Keys.

Nodemailer Configuration Properties

The application will use the Nodemailer module to send email notifications.

To configure nodemailer there are several properties:

config.mailer.from
The sender address you want to use. (Example: John Doe <johndoe@example.com>)
config.mailer.options.service
The Email service you would like to use. (Example: gmail)
config.mailer.options.auth.user
The Email service username.
config.mailer.options.auth.password
The Email service password.
 

Automatically Loaded Files

Through the system we have several object automatically loaded during the application bootstrap. This was done to ease the development process and to help avoid the common mistake of not including your newly created files. The objects that are loaded automatically are:

app/models
Mongoose models are registered automatically during the application bootstrap process. So you can just call themongoose.model(‘modelName‘) whenever you need.
app/routes
Routing files placed in this folder will be registered automatically with the Express application. So whenever you add a new routing configuration, the new routes will be immediately available.
config/strategies
Passport strategies placed in this folder will automatically be loaded by the config/passport.js file. So whenever you add a new strategy, it will be available instantly.
public/modules
The new vertical modules scheme allows us to automatically include the module files in your application HTML file, this includes both JavaScript and CSS files. So have fun creating your modules, and don‘t worry about including your files.
 

NPM

npm is the Node.js package manager that uses a JSON file to configure the backend modules your application will use, the modules will be stored in the node_modules folder.

General Dependencies

Here‘s the description of the default dependencies you‘ll use to bootstrap your MEAN application.

Express
Express is a web framework for Node.js.
Express-Session
Express-Session is the session middleware for Express 4.x applications.
Body-Parser
Body-Parser is a body parsing middleware for Express 4.x applications.
Cookie-Parser
Cookie-Parser is a cookie parsing middleware for Express 4.x applications.
Compression
Compression is a compression middleware for Express 4.x applications.
Method-Override
Method-Override provides faux HTTP method support for Express 4.x applications.
Morgan
Morgan is the connect logger module for Express 4.x applications.
Helmet
Helmet is a set of middlewares that implement various security headers for Express applications.
Glob
Glob provides glob functionality for node.js applications.
Consolidate
Consolidate.js is a template engine consolidation module for Node.js.
Swig
Swig is a template engine for Node.js.
Mongoose
Mongoose is a Mongodb object-modeling module for Node.js.
Connect-mongo
Connect-mongo is a Mongodb session store module for Node.js.
Connect-flash
Connect-flash is a middleware used to store and retrieve messages from the session.
Passport
Passport is an authentication middleware for Node.js that enables authentication from various OAuth sources like Facebook, Twitter, etc.
Passport-Local
Passport-Local is an authentication strategy for passport that enables users to authenticate using username and password.
Passport-Facebook
Passport-Facebook is an authentication strategy for passport that enables users to authenticate using their Facebook account.
Passport-Twitter
Passport-Twitter is an authentication strategy for passport that enables users to authenticate using their Twitter account.
Passport-Linkedin
Passport-Linkedin is an authentication strategy for passport that enables users to authenticate using their Linkedin account.
Passport-Google-OAuth
Passport-Google-OAuth is an authentication strategy for passport that enables users to authenticate using their Google account.
Passport-Github
Passport-Github is an authentication strategy for passport that enables users to authenticate using their Github account.
Lodash
Lodash is a JavaScript utility library, for manipulating collections and objects.
Forever
Forever is a Node.js module that enable node to run continuously. We use it for consistency when running on Heroku.
Bower
Bower is a package manager for front-end components.
Grunt
Grunt is a JavaScript task runner.
Grunt-CLI
Grunt-CLI is Grunt‘s command line interface.
nodemailer
Nodemailer is an email sending module.

Development Dependencies

Here‘s the description of the development dependencies you‘ll use to test and run your MEAN application.

Supertest
Supertest is a library for testing Node.js HTTP API.
Should
Should is an assertion library for BDD testing.
Grunt-Node-Inspector
Grunt-Node-Inspector is grunt task that that runs the node-inspector debugging tool for Node.js applications.
Grunt-Contrib-Watch
Grunt-Contrib-Watch is a grunt task that runs tasks whenever watched file change.
Grunt-Contrib-JSHint
Grunt-Contrib-JSHint is a grunt task that lint JavaScript files using JSHint.
Grunt-Contrib-CSSLint
Grunt-Contrib-CSSLint is a grunt task that lint CSS files using JSHint.
Grunt-NGmin
Grunt-NGmin is a grunt task that pre-minifies AngularJS files.
Grunt-Contrib-Uglify
Grunt-Contrib-Uglify is a grunt task that concat and minifies JavaScript files.
Grunt-Contrib-CSSMin
Grunt-Contrib-CSSMin is a grunt task that concat and minifies CSS files.
Load-Grunt-Tasks
Load-Grunt-Tasks is a grunt task that automatically loads multiple grunt tasks.
Grunt-Nodemon
Grunt-Nodemon is a grunt task that runs nodemon.
Grunt-Concurrent
Grunt-Concurrent is a grunt task that runs tasks concurrently.
Grunt-Mocha-Test
Grunt-Mocha-Test is a grunt task that runs server side mocha tests.
Grunt-Karma
Grunt-Karma is a grunt task that runs karma test runner.
Karma
Karma is a test runner for JavaScript.
Karma-Jasmine
Karma-Jasmine is a karma adapter for the Jasmine testing framework.
Karma-Coverage
Karma-Coverage is a karma plugin that generates code coverage using Istanbul.
Karma-Chrome-Launcher
Karma-Chrome-Launcher is a karma launcher for Chrome and Chrome Canary.
Karma-Firefox-Launcher
Karma-Firefox-Launcher is a karma launcher for Firefox.
Karma-Phantomjs-Launcher
Karma-Phantomjs-Launcher is a karma launcher for PhantomJS.
 

Bower

Notice that .bowerrc configuration file is used to change the default install location to public/lib.

Bower is a front-end package manager that uses a json file to configure the components your application will use. 
Here‘s the description of the front-end components you‘ll use to bootstrap your application.

Bootstrap
Bootstrap is a front-end framework containing many common web development components.
AngularJS
AngularJS is an open-source JavaScript framework.
Angular-Cookies
Angular-Cookies is convenient wrapper for cookies manipulation.
Angular-Resource
Angular-Resource provides interaction support with RESTful services.
Angular-Animate
Angular-Animate provides JavaScript and CSS3 animation support.
Angular-Mocks
Angular-Mocks provides inject and mock support to AngularJS services unit tests.
Angular-Sanitize
Angular-Sanitize provides a functionality to sanitize HTML.
Angular-Bootstrap
Angular-Bootstrap is a set of bootstrap components written in pure AngularJS.
Angular-UI-Utils
Angular-UI-Utils is a set of common utilities for AngularJS.
Angular-UI-Router
Angular-UI-Router provides robust routing and deep linking services for AngularJS applications.
 

Grunt

Grunt is a great tool for automating you JavaScript tasks. The ecosystem is huge, containing many common tasks you can use in your daily development process.

To configure grunt you start with the gruntfile.js file, where you define the tasks you want to run. 
We start with two basic tasks:

  • Default

    The default task is the task that runs when you type ‘grunt‘ in your command-line, the default task consists of three sub-tasks:

    • JSHint

      Linter task that keep your JavaScript code free of common mistakes and syntax errors.

    • CSSLint

      Linter task that keep your CSS code free of common mistakes and syntax errors.

    • Watch

      This watches your file system for changes and automatically reloads the application whenever you change certain files.

    • Nodemon

      This runs your Node.js application using nodemon.

    Please notice that the last two tasks are wrapped with another task called Concurrent to keep the application continuously running.

  • Debug

    Same as default but will also start node-inspector for debugging.

    • JSHint

      Linter task that keep your JavaScript code free of common mistakes and syntax errors.

    • CSSLint

      Linter task that keep your CSS code free of common mistakes and syntax errors.

    • Watch

      This watches your file system for changes and automatically reloads the application whenever you change certain files.

    • Nodemon

      This runs your Node.js application using nodemon.

    • Node-Inspector

      This runs the node-inspector debugging module.

    Please notice that the last two tasks are wrapped with another task called Concurrent to keep the application continuously running.

  • Lint

    This task runs when you type ‘grunt lint‘ in your command-line, the test task consists of two sub-tasks:

    • JSHint

      Linter task that keep your JavaScript code free of common mistakes and syntax errors.

    • CSSLint

      Linter task that keep your CSS code free of common mistakes and syntax errors.

  • Build

    This task runs when you type ‘grunt build‘ in your command-line, the test task consists of two sub-tasks:

    • JSHint

      Linter task that keep your JavaScript code free of common mistakes and syntax errors.

    • CSSLint

      Linter task that keep your CSS code free of common mistakes and syntax errors.

    • LoadConfig

      A task that loads the environmental configuration file for the uglify and cssmin tasks.

    • NGMin

      A task that pre-minifies AngularJS files.

    • Uglify

      A task that concat and minifies JavaScript files.

    • CSSMin

      A task that concat and minifies CSS files.

    Remember to use the build task before deploying your application to a production environment.

  • Test

    This task runs when you type ‘grunt test‘ in your command-line, the test task consists of three sub-tasks:

    • Env:test

      This is a simple task that changes the NODE_ENV global environment variable to ‘test‘.

    • MochaTest

      This runs the mocha server tests that are located in the app/tests folder.

    • Karma:unit

      This uses the karma test runner to run the AngularJS unit tests.

We recommend that you visit Grunt‘s Documentation Section to learn more about writing your own tasks, and mainly toexplore the tasks already written by the community.

 

Express & Routing

Express is web framework for the Node.js platform. Its robustness and minimalism made it very popular among Node.js developers.

Express configuration is done in the config/express.js In the express.js file the application is initialized and configured, automatically loading the routes files in the app/routes folder, which contains the set of routes the application will serve.

There are a few pre-bundled routes:

Authentication Routes

Authentication routes are located in the app/routes/users.server.routes.js file.

GET http://localhost:3000/users/me
Returns the current authenticated user.
POST http://localhost:3000/auth/signup
This is used to sign up a user using username and password.
POST http://localhost:3000/auth/signin
This is used to sign in a user using username and password.
GET http://localhost:3000/auth/signout
This is used to sign out the current user.
GET http://localhost:3000/auth/facebook
This is used to initialize the Facebook OAuth process.
GET http://localhost:3000/auth/facebook/callback
This is used as the callback URI for Facebook OAuth process.
GET http://localhost:3000/auth/twitter
This is used to initialize the Twitter OAuth process.
GET http://localhost:3000/auth/twitter/callback
This is used as the callback URI for Twitter OAuth process.
GET http://localhost:3000/auth/linkedin
This is used to initialize the Linkedin OAuth process.
GET http://localhost:3000/auth/linkedin/callback
This is used as the callback URI for Linkedin OAuth process.
GET http://localhost:3000/auth/google
This is used to initialize the Google OAuth process.
GET http://localhost:3000/auth/google/callback
This is used as the callback URI for Google OAuth process.
GET http://localhost:3000/auth/github
This is used to initialize the Github OAuth process.
GET http://localhost:3000/auth/github/callback
This is used as the callback URI for Github OAuth process.

Please notice that you can add more authentication options using a Passport Strategy and this pattern.

Application Routes

Application core routes are located in the app/routes/core.server.routes.js file.

GET http://localhost:3000/
The main application page. Using AngularJS helps reduce the use of server side templating, and only serve a single application page. 

To learn more about this visit the Backend Views section.

Example Routes

An ‘Article‘ example is included with the boilerplate to help you understand how to properly build your RESTful API, the routes for this module are located in the app/routes/articles.server.routes.js file.

GET http://localhost:3000/articles
Returns the list of articles.
POST http://localhost:3000/articles
Creates a new article.
GET http://localhost:3000/articles/:articleId
Returns an article by articleId.
PUT http://localhost:3000/articles/:articleId
Updates an article by ID.
DEL http://localhost:3000/articles/:articleId
Deletes an article by ID.

To learn more about Express you should visit the Guide Section in the official website.

 

Passport

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 6 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.
Twitter
The Twitter Strategy is used to authenticate users via their Twitter 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.
Github
The Github Strategy is used to authenticate users via their Github account.

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

 

Backend Views

AngularJS reduces the need for server side templating. What once was a web application served by server as HTML pages can now be implemented using Angular‘s template system.

So why do you still keep a views folder in your app folder?

There are few answers to this question:

  1. You still need to render the index and error page.
  2. You might need to render HTML templates for your email notifications.
  3. You want to render local configuration properties in the template. For instance, the title property from the configuration file can be used in the title element of the HTML page.
  4. AngularJS module system is implemented in a way that allows you to automatically load the modules .js files in template.

So we can‘t use static templates, and we have to use some kind of template engine, but which one?

Swig Template Engine

Swig is a template engine, written by Paul Armstrong.

While JADE is the default template engine used by Express, and is by far the most popular template engine, it doesn‘t suit this boilerplate for several reasons:

  1. It‘s slower.
  2. It uses its own language, steeping the learning curve.
  3. You don‘t need it! JADE‘s greatest advantage is to facilitate the task of writing a lot of HTML that is being served by the server. You‘re going to use AngularJS client templating engine, thus relieving the need for server templating.

On the other hand, using Swig has a few advantages:

  1. It‘s faster, as in way faster.
  2. It uses HTML.
  3. It has all the features we need to render our index and error pages!

To summarize, when coding a Node.js website, you might want to use other template engines, but approaching web application development using AngularJS, we think Swig is the best choice.

To understand Swig better we recommend that you visit the Official Website.

The Views

There are 4 files in the views folder:

Layout
This is most important file, which sets the layout used to render all the other templates.
Index
The index template is served as the main application page.
404
The 404 error template is served whenever express cant find a routing scheme for the current path.
500
The 500 error template is served whenever there‘s a server error.

The Templates

The templates folder is placed inside the views folder and currently contains 2 files:

Reset Password Email
An email template sent to users after they‘ve request to reset their password.
Reset Password Confirmation Email
An email template sent to users after they‘ve reset their password.
 

Server Tests

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 the app/tests folder.

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.

To learn more about how to write your tests visit The Article Example Section.

 

AngularJS Tests

Testing is an important feature of the AngularJS framework. It is so well established that the team has create a very cool to automate tests, the Karma Test Runner.

The Karma Test Runner is a unique testing tool that enables you to automatically test your code on multiple real browsers using Node.js and Socket.io.

Karma is not a testing library, it utilizes other testing frameworks to test your code and comes with different framework adapters, supporting the common testing frameworks.

In the AngularJS documentation the team uses Jasmine Testing Framework to unit test the application. So, in the boilerplate we use Jasmine as well.

Now AngularJS supports two kind of tests:

E2E
End-To-End testing enables to test several parts of the application together, so instead of just testing your controller‘s methods, you can actually test different scenarios in your application. To understand it better visit the AngularJS E2E Testing Section.
Unit
Unit testing is the more common testing method, which enables you to test different units of the application, it‘s a more detailed kind of testing, which neglects the bigger picture and focuses on the single unit functionality. To understand it better visit the AngularJS Unit Testing Section.

In the example provided there are only unit tests, E2E should come out in the next version.

Karma Configuration

Karma configuration file, karma.conf.js, is the located at the root folder. You can learn more about the different configuration properties in the Configuration Section on the official website. 
But here is a quick review of the properties used in the boilerplate:

Frameworks
The testing framework you want to karma to use, in this case we‘ll use Jasmine.
Files
This is really important! This is the list of files that karma should load before starting the tests.

Notice that we load the angular module tests automatically, so whenever you add a new module, Karma will run your tests without you having to change anything at all.

LogLevel
Determines the logging level of karma console output.
Browsers
Determines which browsers to launch when testing, the boilerplate comes pre-bundled with 3 launchers: Chrome, Firefox, and PhantomJS.
SingleRun
Determines if karma will run one time and return the results, or stay connected to watch for changes.

Notice that karma is executed as a grunt task that looks for the configuration file.

Unit Testing

In the Article examples attached, there‘s a unit test example in the tests/article.spec.js file. Notice that we use angular-mocks to simulate the HTTP requests. The tests are defined to cover all the CRUD operations, and will test the $resource service as well.

There are a few common steps we use to unit test the application:

  1. In the beforeEach function 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.
  5. Finally use Jasmine matchers to test the result.

To learn more about how to write your tests visit The Article Example Section.

 

AngularJS Modules

When we started with MEAN one of our major concerns was how to structure our AngularJS application, and on the first few AngularJS applications, we used the great AngularJS Seed Project provided by the AngularJS team. 
The basic structure for this project is quite simple:

|-css|---app.css|-img|-js|---app.js|---controllers.js|---directives.js|---filters.js|---services.js|-partials|---partial1.html|---partial2.htmlindex.html

Notice that in the JS folder there are a few pre-bundled files. Basically you just place all your controllers in the controllers.js file, all your services in the services.js file, and so on. This is nice for a single developer working on a small project, but when working on production web application, pretty soon you get bloated JS files, which create real issues when trying to work in a team.

Then we changed the structure a bit to look something like this:

|-css |---app.css |-img |-js |---app.js|---controllers|-----controller1.js|-----controller2.js|---directives|-----directive1.js|----- directive2.js|---filters|-----filter1.js|-----filter2.js|---services|-----service1.js|-----service2.js|-partials|---partial1.html|---partial2.htmlindex.html

Reorganizing the project this way helped us create bigger projects that are more maintainable in the long term. For a while we had fun using this but lately we found out that wasn’t enough. Now instead of bloating a single JavaScript file, we had pretty big folders containing ~20 controllers, and even more views in the partials folder.

Luckily, when the original MEAN.IO boilerplate gained some traction, we got a chance to talk to some great AngularJS developers writing blogs and working on some popular libraries. One of the greatest topics in our conversations was Angular’s modularity.

AngularJS Module System

AngularJS module system is a core feature when developing AngularJS applications; actually every AngularJS application is basically an AngularJS module. The other thing about AngularJS modules is that when defining a module you can also include sub-modules as dependencies. It usually looks something like this:

angular.module(‘FirstDependency’, []);angular.module(‘SecondDependency’, []); angular.module(‘MainModule’, [‘FirstDependency’, ‘SecondDependency’]);

In this example we define the first and second modules and then we define the main module with the two sub-modules as dependencies. Later when you want to define an AngularJS entity you can simply use the sub modules as way to separate your application logic. For example defining a controller will look something like this:

angular.module(‘FirstDependency’).controller(…);

AngularJS Horizontal Modules

In their seed project, the AngularJS team recommends using modules in a horizontal way that ends up looking like this:

angular.module(‘application.controllers’, []);angular.module(‘application.services’, []);angular.module(‘application’, [‘application.controllers’, ‘application.services’]);

With this approach you arrange your AngularJS entities in horizontal modules that represents their role:

Application
ControllersDirectivesFiltersServices
Controller1Directive1Filter1Service1
Controller2Directive2Filter2Service2
Controller3Directive3Filter3Service3

Although this helps create fewer modules those modules wont represent the higher functionality of each entity, for example all the controllers are defined under the same module regardless of their actual purpose. While this is suitable for small projects, using horizontal modules doesn‘t scale well for bigger projects.

Vertical Modules Are Better

During our conversation with some of the main contributors to the popular Angular-UI, they pointed this issue to us. When we observed our AngularJS applications we discovered it would be better to restructure our applications in a vertical manner:

Application
Core ModuleUsers ModuleArticles Module
CoreController1UsersController1ArticlesController1
CoreController2UsersController1ArticlesController2
CoreService1UsersService1ArticlesService1
CoreFilter1UsersFilter1ArticlesFilter1
CoreDirective1UsersDirective1ArticlesDirective2

This helped us divide the project logic into modules that represent individual logical units, and it didn‘t surprised us to find out the Angular-UI projects uses the same approach.

New Folder Structure

Using vertical modules only solves half the problem because we still use horizontal approach in our folder structure. This means that all your application controllers will reside in the same folder, as are all the services, directives, filters, and views. In this case you wouldn’t be able to associate a file with its module until you open it.

So we converted our application structure to a vertical structure to fit the vertical modular approach:

						|-css |-img |-js |-modules |---articles |-----config |-----controllers |-----services |-----tests |-----views|---core|-----config|-----controllers|-----tests|-----views|---users|-----config|-----controllers|-----services|-----views

In this case we have 3 modules:

Core
Containing the application core configuration, controllers, test, and views.
Users
Containing the application authentication configuration, controllers, services, and views.
Articles
The example module we added, that contains article related configuration, routing, controllers, services, tests, and views.

This structure allow clear separation of functionality and concerns, so just by looking at the folder structure you can start asking questions about your modules, for example why does the users module have no tests? (hint: Its our fault and we plan to add those :)).

But we didn’t want to stop at this point!

Because we are building a full-stack solution, won’t it be great if module files could be automatically included in the backend view HTML, eliminating common import mistakes? We do two things to help with this issue:

  1. In the config/express.js file, we iterate over the modules folder to automatically add the .JS and .CSS files to the layout HTML.
  2. There two kind of modules you‘ll add to your application: third-party modules and custom modules.

    To add third-party modules use the public/config.js file where we added an array property calledapplicationModuleVendorDependencies. When you add a new third-party module you should add it to this array so the main module can load it as a depenedency.

    To register your own module, we created the ApplicationConfiguration.registerModule method. To add your custom module and your module and it will automatically be loaded as a dependency to the AngularJS main application module.

This method has a few advantages:

  1. Team members have a method of organizing their code, so every module will look the same.
  2. Everyone has a clearer and broader view of the project.
  3. Working together becomes faster, especially in merging the different development branches.
  4. Because this is very structured you can start automating some common tasks, like creating a new module, verifying an existing module, etc.(Hmmm... Future Generator)
  5. You can avoid common mistakes by not including all the JS files, or forget to add your module as a dependency to the main module.
  6. Reusage of modules is now easier because you can just seamlessly copy your module folder to another project.
  7. Third party modules can now be easily shared and implemented.

ApplicationConfiguration

While the angular module system is quite robust it lacks a few options, mainly the abiliy to add dependencies to the main module after it was already created. Because of that we use the ApplicationConfiguration object to maintain a list of modules, which the main module will use as depenedencies. If it weren‘t for the ApplicationConfiguration, you would have to register your module in two place:

  1. When you create your module using the angular.module(...)method.
  2. When you create your main application module you‘ll have to register your module as a dependency in the dependencies list.

This can become an annoying pitfull, so we added the ApplicationConfiguration that is loaded before all the modules file. TheApplicationConfiguration global object expose a method named registerModule, this method will create the new angular module and add it to list of dependencies of the main application module.

We recommend that you take a look at the code that is placed inside the /public/config.js file.

Module Structure

So how should you add a new module?

To add a new module, you’ll have to create a new folder in the public/modules folder. The directory structure should look something like this:

|-module |---config |---controllers |---css |---directives |---filters |---img |---services |---tests |---views |---module.js

In each folder you‘ll include the appropriate module entities, you can also delete the empty folders to keep it clean.

Finally you have to add your module.js file, which should look something like this:

‘use strict‘;// Use Applicaion configuration module to register a new moduleApplicationConfiguration.registerModule(‘moduleName‘);

Thats it! This way the registerModule method will create your module and push it to the dependencies list of your AngularJS main application module. 
MEAN will take care of everything else, like including those files in the layout HTML and bootstrap the AngularJS application using your module as a dependency.

Module Tests

Adding Karma tests is a simple task, and you can follow the Article Example to learn all about it.

But here is another neat feature: loading your module tests is also done automatically! Karam config file will iterate through the module folder and add your new module tests as well. Don‘t worry! if you haven‘t written any tests karma will skip your module and just run the tests you already have.

Notice: Your test files should be placed in the module/tests folder or else MEAN won‘t ignore them and add them in the HTML as script files.

 

AngularJS Menus Service

In the 0.3.x version, MEAN.JS has introduced a new 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.
Menus.addMenu(menuId, [isPublic], [roles])
Creates a new menu object, which will be identified by the menuId argument. This method also include three arguments:
  1. menuId (Required) - Indicates the menu identifier for future reference.
  2. isPublic (Optional; Default: false) - Indicates whether a menu should be displayed only to authenticated users.
  3. roles (Default: [‘user‘]) - An array indicating the roles that are allowed to view this menu.
Menus.addMenuItem(menuId, menuItemTitle, menuItemURL, [menuItemUIRoute], [isPublic], [roles]);
Creates a new menu item object. This method also include couple of arguments:
  1. menuId (Required) - Indicates the menu identifier.
  2. menuItemTitle (Required) - A String title for the menu item.
  3. menuItemURL (Required) - The path this menu item will link to.
  4. menuItemUIRoute (Optional; Default: menuItemURL) - The UIRoute value, which is used to define the URL scheme where this menu item is marked as active.
  5. isPublic (Optional; Default: menu.isPublic) - Indicates whether a menu item should be displayed only to authenticated users.
  6. roles (Optional; Default: [‘user‘]) - An array indicating the roles that are allowed to view this menu item.
Menus.addSubMenuItem(menuId, rootMenuItemURL, menuItemTitle, menuItemURL, [menuItemUIRoute], [isPublic], [roles]);
Adds a submenu item to an existing item object. This method also include couple of arguments:
  1. menuId (Required) - Indicates the menu identifier.
  2. rootMenuItemURL (Required) - Indicates the root menu item identifier.
  3. menuItemTitle (Required) - A String title for the menu item.
  4. menuItemURL (Required) - The path this menu item will link to.
  5. menuItemUIRoute (Optional; Default: menuItemURL) - The UIRoute value, which is used to define the URL scheme where this menu item is marked as active.
  6. isPublic (Optional; Default: menu.isPublic) - Indicates whether a menu item should be displayed only to authenticated users.
  7. roles (Optional; Default: [‘user‘]) - An array indicating the roles that are allowed to view this menu item.

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) {		// Set top bar menu items		Menus.addMenuItem(‘topbar‘, ‘Example‘, ‘example‘);	}]);

To learn more about the Menus service, visit The Article Example Section.

 

The Article Example

The Article example is an end-to-end example that includes the basic CRUD operations, which are most commonly used in content websites. It is divided into two parts: The Express backend module, and The AngularJS front-end module.

Express Backend Module

We mostly use the Express application as a RESTful API for the AngularJS application. This means the common MVC architecturecan be reduced to an MC architecture, where the Model represent the data entities in the system, while the Controller is in charge of the business logic, leaving the View part only in the AngularJS application.

Mongoose Model

Mongoose is a Node.js schema-based object-modeling module. Mongoose models are defined using a Schema object that allows you to model and validate your data.

The Mongoose Schema

The Mongoose schema is used to define the structure of your application‘s data. Entries are called Documents in the MongoDB context, and schemas describe what types of properties they have, and what references and relations exist between them.

In our article example, we define the type of each property, as well as a possible default value. When necessary, we can also use properties like "trim" to make sure our data is properly transformed before it is saved.

Using Validations and Middleware

We can make sure the data we save complies with specific validation tests, and reject entries, which do not comply. In our example, we validate the title returns a true result for "title.length", to ensure it isn‘t blank. Similarly, we could run any function on the data being saved, and enforce whatever policy we want.

Middleware is used whenever we want to execute code before or after we run any kind of operation on an entry. This gives us the opportunity to carry out validation, authorization, monitoring and other operations, before (or after) the entry is operated upon.

How statics are defined

We can extended the methods we build into the schema. In our example, we added a "load" method to the article schema, which allows us to automatically load an article, and populate a reference to the document describing the article‘s author.

 

To learn more about Mongoose you should visit the Official Website.

Express Controller

In MEAN, the controllers are where you‘d query your database, and preform any server-side calculations before relaying the data to the client. In the example articles controller example we define the basic CRUD operations and other required methods:

create
The create method creates a new Article document.
read
The read method returns a single article.
update
The update method updates a single article.
delete
The delete method removes a single article.
list
The list method returns a list of articles.
articleByID
The articleByID method sets the current article object by its ID.
hasAuthorization
The hasAuthorization method checks if the current user created the current article.

Express Routes

In order to expose the controller methods as REST endpoints, we assign the controller methods to Express endpoints. This is done in the app/routes/articles.js file. Here we also hook up the middleware used to make sure a request for updating or removing the article is only allowed by an authorized user.

Here are the routes we defined for the article example:

GET http://localhost:3000/articles
Returns the list of articles.
POST http://localhost:3000/articles
Creates a new article.
GET http://localhost:3000/articles/:articleId
Returns an article by articleId.
PUT http://localhost:3000/articles/:articleId
Updates an article by ID.
DEL http://localhost:3000/articles/:articleId
Deletes an article by ID.

Express Mocha Tests

We use Mocha tests to verify our model. In this case the we added a test example that cover the article save method. The test is self is broken into three parts:

  • Before Testing

    Before we test the article save method, we‘ll create the user object, then save it, and in the callback create a new article object.

  • The Tests

    Now we‘re ready to perform our tests. In the first test we‘ll try to save the article, then use the should assertion libraryto verify it was saved without an error.

    In the second test, we‘ll check the article model validation. We‘ll set the title property to an invalid value, then try to the save the document, we‘ll use should again to verify that an error has occurred.

  • After The Test

    Once our testing is over, we can now do cleanup and remove the documents from our test database.

To understand BDD better please visit the Official Mocha Website.

AngularJS Front-End Module

Folder Structure

Each AngularJS module is organized in an isolated folder containing the logical structure of the module functionality. In the Article example case, that folder is located at public/modules/articles. This is the folder structure of the Article module:

config
The config folder contains any AngularJS configuration related to the articles module, for instance this folder contains the routes.js file, which defines the AngularJS routing for the articles module.
controllers
The controllers folder contains any AngularJS controllers related to the articles module.
services
The services folder contains any AngularJS services related to the articles module.
tests
The tests folder contains any Jasmine tests related to the articles module.
views
The views folder contains any AngularJS partial views related to the articles module.

The module folder structure is dynamic and may contain any components related to that module. While the article example is simple, modules can become much more complex, and may contain several services, controller, directives, etc.

AngularJS Service

The client-side of the article entities is connected to the Express route through an AngularJS Service. In this case, we usengResource to easily connect our RESTful endpoints to Express.

The $resource service supports RESTful CRUD endpoints out of the box, except for the update method which requires specifically defining it to use the PUT verb.

AngularJS Controller

The AngularJS controller is where you‘ll write your logic, in this case the controller is simply corresponding to the RESTful service CRUD operations:

create
The create method is used to create new articles.
remove
The remove method is used to delete an article.
update
The update method is used to update an article.
findOne
The findOne method is used to fetch a single article.
find
The find method is used to fetch a list of articles.

AngularJS Views

The AngularJS views render the data passed through the controller, in this case each view is a visual representation of a CRUD operation:

create-article.client.view.html
The create.html view is used to create an article.
view-article.client.view.html
The view.html view is used to present a single article.
edit-article.client.view.html
The edit view is used to update an article.
list-articles.client.view.html
The list view is used to view a list of articles.

AngularJS Routes

AngularJS use the UI-Router module to define the various routes of the module. Each route is defined using the $stateProviderservice, and defines a path to the template, which will be rendered when navigating to a specific URL.

In this example we configured 4 routes:

/#!/articles
When navigating to this URL, UI-Router will render the list-articles.client.view.html view.
/#!/articles/create
When navigating to this URL, UI-Router will render the create-article.client.view.html view.
/#!/articles/:articleId
When navigating to this URL, UI-Router will render the view-article.client.view.html view.
/#!/articles/:articleId/edit
When navigating to this URL, UI-Router will render the edit-article.client.view.html view.

Notice that we define a routing parameter called articleId, to grab it later in the controller and fetch the correct article.

AngularJS Menu Items

Your stack is bundled with an AngularJS Menus Service that enables to add menu items directly from the module configuration file. In the article example you can see how the two menu items are added to the top bar menu in thearticles.client.config.js file:

angular.module(‘articles‘).run([‘Menus‘,	function(Menus) {		// Set top bar menu items		Menus.addMenuItem(‘topbar‘, ‘Articles‘, ‘articles‘, ‘dropdown‘, ‘/articles(/create)?‘);		Menus.addSubMenuItem(‘topbar‘, ‘articles‘, ‘List Articles‘, ‘articles‘);		Menus.addSubMenuItem(‘topbar‘, ‘articles‘, ‘New Article‘, ‘articles/create‘);	}]);

 

AngularJS Unit Tests

AngularJS Jasmine tests are a bit trickier, but are mostly done in the same way as Mocha.

  • Before Testing

    Before testing the article controller, there a few prerequisites we need to take care of:

    • Initialize the global variables.
    • Add a Jasmine Matcher that compares objects while ignoring the object methods.
    • Load the main application module.
    • Use the inject function to:
      1. Point the global variables to the AngularJS services we are about to use.
      2. Create a new ArticleController instance.
  • The Test

    Most of your tests will look quite the same and will include similar steps:

    • First you‘ll have to create your sample data.
    • Then, use Angular-Mocks to set the httpBackend expected response.
    • Call the controller method you would like to test.
    • Then, use httpBackend.flush() to emulate server response.
    • Finally, use a Jasmine matcher to verify the test result.

To understand AngularJS unit testing better, please visit the Unit Testing Section in the official website.

MEANJS DOC