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:
css
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.html
In this section you'll learn how to get started with a MEAN.JS application, install all the prerequisites, and initialize your application.node
Before you begin, you should make sure you have installed all these prerequisites on your development machine.ios
$ npm install -g bower
$ npm install -g grunt-cli
Note: Your user might not have the permissions to install package globally, so use a super user or sudo.git
There are several ways you can get the MEAN.JS boilerplate:angularjs
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.github
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.web
You can also use Git to directly clone the MEAN.JS repository:mongodb
$ git clone https://github.com/meanjs/mean.git meanjs
This will clone the latest version of the MEAN.JS repository to a meanjs folder.chrome
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.
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:
bower install
command to install all the front-end modules needed for the 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.
During the installation process you may encounter some problems, so what can you do?
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.
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.
$ npm update -g npm
$ npm update -g bower
$ npm update -g grunt-cli
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.
$ npm cache clean
$ bower cache clean
There are some common errors while installing mean:
$ bower updateThis will install the missing packages.
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.
The folder structure is quite self-explanatory, but here's an explanation on what goes where and why.
The server folder contains all the server files you use in your application, this is where you store your MVC server files.
When to use: Whenever you want to add, change, or remove Express application controllers.
When to use: Whenever you want to add, change, or remove Mongoose models.
When to use: Whenever you want to add, change, or remove a server route.
When to use: Whenever you want to add, change, or remove Mocha tests.
When to use: Whenever you want to add, change, or remove backend views.
When to use: Whenever you want to add, change, or remove backend templates.
The config folder contains the files you need to configure your application.
When to use: Whenever you want to add, change, or remove your configuration properties.
When to use: Whenever you want to add, change, or remove a Passport Strategy.
When to use: Whenever you want to change the way Express is being initialized and configured.
The public folder contains all the static files you use in your application, this is where you store your front-end files.
When to use: Whenever you want to add, change, or remove AngularJS modules.
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.
When to use: Whenever you want to add, change, or remove a module in your AngularJS application.
There are a few application files stored in root folder.
When to use: Whenever you want to add, change, or remove front-end components.
When to use: Whenever you want to configure your Docker images.
When to use: Whenever you want to add, change, or remove grunt tasks.
When to use: Whenever you want to add, change, or remove front-end tests.
When to use: Whenever you want to add, change, or remove backend modules.
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.
When to use: Whenever you want to add, change, or remove CSSLint properties.
When to use: Whenever you want to add, change, or remove files that are ignored by Git.
When to use: Whenever you want to add, change, or remove JSHint properties.
When to use: Whenever you want to add, change, or remove files that are ignored by Heroku slug compiler.
When to use: Whenever you want to add, change, or remove TravisCI configuration options.
So, you have your application running, but how do you configure it?
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:
To run your application with a different environment configuration run the application like this:
$ NODE_ENV={The Environment Name} grunt
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:
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:
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.
Note: You can also include CDN paths to load packages files directly from their official CDN.
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:
Remember to use different configuration for each environment especially your MongoDB URI and social platform OAuth Keys.
The application will use the Nodemailer module to send email notifications.
To configure nodemailer there are several properties:
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:
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.
Here's the description of the default dependencies you'll use to bootstrap your MEAN application.
Here's the description of the development dependencies you'll use to test and run your MEAN application.
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.
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:
The default task is the task that runs when you type 'grunt' in your command-line, the default task consists of three sub-tasks:
Linter task that keep your JavaScript code free of common mistakes and syntax errors.
Linter task that keep your CSS code free of common mistakes and syntax errors.
This watches your file system for changes and automatically reloads the application whenever you change certain files.
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.
Same as default but will also start node-inspector for debugging.
Linter task that keep your JavaScript code free of common mistakes and syntax errors.
Linter task that keep your CSS code free of common mistakes and syntax errors.
This watches your file system for changes and automatically reloads the application whenever you change certain files.
This runs your Node.js application using nodemon.
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.
This task runs when you type 'grunt lint' in your command-line, the test task consists of two sub-tasks:
Linter task that keep your JavaScript code free of common mistakes and syntax errors.
Linter task that keep your CSS code free of common mistakes and syntax errors.
This task runs when you type 'grunt build' in your command-line, the test task consists of two sub-tasks:
Linter task that keep your JavaScript code free of common mistakes and syntax errors.
Linter task that keep your CSS code free of common mistakes and syntax errors.
A task that loads the environmental configuration file for the uglify and cssmin tasks.
A task that pre-minifies AngularJS files.
A task that concat and minifies JavaScript files.
A task that concat and minifies CSS files.
Remember to use the build task before deploying your application to a production environment.
This task runs when you type 'grunt test' in your command-line, the test task consists of three sub-tasks:
This is a simple task that changes the NODE_ENV global environment variable to 'test'.
This runs the mocha server tests that are located in the app/tests folder.
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 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 are located in the app/routes/users.server.routes.js file.
Please notice that you can add more authentication options using a Passport Strategy and this pattern.
Application core routes are located in the app/routes/core.server.routes.js file.
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.
To learn more about Express you should visit the Guide Section in the official website.
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:
To understand Passport better we recommend that you visit the Guide Section in the official website.
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.
There are few answers to this question:
So we can't use static templates, and we have to use some kind of template engine, but which one?
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:
On the other hand, using Swig has a few advantages:
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.
There are 4 files in the views folder:
The templates folder is placed inside the views folder and currently contains 2 files:
We use Mocha to test the server side logic. Mocha tests are asynchronous, easy to maintain, and uses a readable BDD syntax.
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.
Each entity have its own test file located inside the app/tests folder.
There are a few common steps we use to test an entity:
To learn more about how to write your tests visit The Article Example Section.
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:
In the example provided there are only unit tests, E2E should come out in the next version.
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:
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.
Notice that karma is executed as a grunt task that looks for the configuration file.
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:
To learn more about how to write your tests visit The Article Example Section.
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.html index.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.html index.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 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(…);
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 | |||
---|---|---|---|
Controllers | Directives | Filters | Services |
Controller1 | Directive1 | Filter1 | Service1 |
Controller2 | Directive2 | Filter2 | Service2 |
Controller3 | Directive3 | Filter3 | Service3 |
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.
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 Module | Users Module | Articles Module |
CoreController1 | UsersController1 | ArticlesController1 |
CoreController2 | UsersController1 | ArticlesController2 |
CoreService1 | UsersService1 | ArticlesService1 |
CoreFilter1 | UsersFilter1 | ArticlesFilter1 |
CoreDirective1 | UsersDirective1 | ArticlesDirective2 |
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.
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:
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:
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:
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:
angular.module(...)
method.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.
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 module ApplicationConfiguration.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.
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.
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:
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 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.
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 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 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.
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.
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.
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:
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:
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 we test the article save method, we'll create the user object, then save it, and in the callback create a new article object.
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.
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.
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:
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.
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.
The AngularJS controller is where you'll write your logic, in this case the controller is simply corresponding to the RESTful service CRUD operations:
The AngularJS views render the data passed through the controller, in this case each view is a visual representation of a CRUD operation:
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:
Notice that we define a routing parameter called articleId, to grab it later in the controller and fetch the correct article.
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 Jasmine tests are a bit trickier, but are mostly done in the same way as Mocha.
Before testing the article controller, there a few prerequisites we need to take care of:
Most of your tests will look quite the same and will include similar steps:
To understand AngularJS unit testing better, please visit the Unit Testing Section in the official website.