This is a MEAN (Mongo, Express, AngularJS, Node) seed enhanced & recharged (MEANER). This is partly based on mean.io and ngBoilerplate which are 2 great seeds projects for mean and angularjs.
This is still a work in progress. I'm using it now for a personal project and I'll keep improving it while I use it.
I created this because I saw some things that I didn't like on all MEAN seeds, so I decided to roll out my own :).
This are the things that I didn't like of other MEAN seeds:
- They didn't handle JS minification, concatenation, ngMin, etc. I want my dev code to be unminified and separated but I want my production code to work with minified files.
- They didn't handle Less/css minification, concatenation, transformations for prod and dev.
- Frontned code wasn't feature separated like ngBoilerplate
- Gruntfile was mostly for only server or only frontned. I wanted with one Gruntfile to be able to run the app.
- They didn't have a good and clear folder structure for both FrontEnd and Backend.
- They didn't have the ability to have both Frontend powered (SPA) pages and backend power pages.
So what I did here is to take the both of mean.io and ngBoilerplate, mix it with some of my code and configurations and et voila. Here is the new mean seed.
You can just clone this repository, run npm install
, bower install
, mongod
, grunt
and you're set to go. After that, the app will be running on http://localhost:3000
meaner/
|- app/
| |- controllers/
| | |- <backend controllers>
| |- models/
| | |- <backend models>
| |- routes/
| | |- <backend routes>
| |- views/
| | |- <backend views and layouts>
|- tests/
| |- <Tests for Backend code (Mocha + Supertest)>
|- assets/
| |- <Built / Compiled frontend code: Minified, concatenated, transformed,etc>
|- config/
|- frontend/
| |- app/
| | |- <all Angular apps code including JS, tests, Less>
| |- common/
| | |- <all Angular code that is reusable (Services, Directives)>
| |- vendor/
| | |- <Front end dependencies installed via bower>
| |- styles/
| | |- <Less files to be used for non angular apps (except for shared)>
| | |- shared/
| | | |- <All less files to be used in Angular app and Static app>
|- .bowerrc
|- bower.json
|- build.config.js
|- Gruntfile.js
|- package.json
Please feel free to go to each folder and check out the code and run the app. This is the basic structure for the app.
You're going to be using grunt to start/run the application.
Running grunt
or grunt watch
will start the application and watch for changes in either Frontend or Backend code. If there's a change, Livereload will reload the entire website. It runs node
using nodemon
grunt watch
also takes care of processing frontend code so that it's available to use. It'll create CSS files from Less files, add the script
and link
tags to your HTML so that all of your frontned code is linked from the HTML, it'll convert all of your HTML templates to JS using html2js
so that it doesn't have to do a request to get the templates and much more. You can view all tasks in the Gruntfile.js
.
You can use grunt test
to run all of your backend (mocha + supertest) tests and frontned (karma) tests :). Backend tests are located in tests/
and frontned test are inside frontend folder with spec.js
extension.
For production, you'll need to run grunt compile
. Besides doing all the things as grunt watch
, it'll also minify and concatenate all JS, CSS and less files and change the script
and link
tags in your HTML to just this one dependency. This will make your code ready to be deployed.
If you're deploying this to Heroku, I've already configured the correct buildpack which will take care of all of this once you push.
Summing up, the grunt commands are:
grunt
orgrunt watch
: Starts NodeJS in Dev mode and creates assets folder from FrontEnd for development (less to css, html2js, etc.). It also has livereload for EVERYTHING.grunt test
: Tests backend and frontend codegrunt compile
: Prepares your code for production. Does minification, concatenation and changes all scripts and link tags to compiled assets.grunt heroku
: Prepares your env for heroku.
Now, it's time to code. So, where do we start? A few tips on places to look and stuff to check:
- You need to add a new file in routes stating your routes and to which controller they point to. If you're going to use Angular for this page, I recommend you to use html5mode and add a route to
yourRoute/*
- You can add then your controller for that route
- You need to create a view. Here, you can inherit from either defaultServer or defaultSPA. If you want this page to have Angular and use Angular stuff, inherit from defaultSPA. You'll see examples of both things in this seed project
- If you chose an AngularApp, you need to set the
ng-app
in your template and then you can create that app in Frontend. If you'll just have one main Angular app, just add it inside/frontend/app
otherwise, I'd recommend creating a folder for each.
The main idea here is to let people have "multiple SPAs". I don't like having just one SPA where if the user changes the URL, we change absolutely everything he's watching on Client side. So, what you can do here, is to actually have multiple SPAs at different URLs. So let's see an example:
You could have a /user/*
spa where we'd show all user settings. All that page with its tabs, and everything will be Angular code. But, if you click on the Accounts button for example, it'll send you to a different server page which is mapped to /accounts/*
which will be another SPA for all account related stuff.
I like this way of ordering code. However, if you prefer just ONE main SPA and that's it, you can easily do that with this meaner-seed as well :). All you will do is to actually map /app/*
to the Angular app and then just have everything in there. And then, you'd have a server rendered page on /
maybe which is the only page outside of Angular. That way, you'd just have 2 views, one would inherit from defaultSPA
and one from defaultServer
. I hope that this explanation is clear, otherwise PLEASE create an issue and I'll try to explain this better :).
With those steps, you're ready to go to add your code
Now, what if you want to add Frontend dependencies?
You first must add it to bower.json
. After running bower install
, the dependency will be installed to /frontend/vendor
.
Now, you have to go to the build.config.js
and locate some properties:
js_vendor_all
: In this property you need to add the path to each new JS file you want to add from the libraries you chose. After doing this, the script tag will automatically be added by itself in dev and concatenated will other libs on prod for both angular pages and non angular pagesjs_vendor_angular
: In this property you need to add the path to each new JS file you want to add from the libraries you chose. After doing this, the script tag will automatically be added by itself in dev and concatenated will other libs on prod only for angular pagesjs_vendor_non_angular
: In this property you need to add the path to each new JS file you want to add from the libraries you chose. After doing this, the script tag will automatically be added by itself in dev and concatenated will other libs on prod only for NON angular pagescss_vendor_all
: In this property you need to add the path to each new CSS file you want to add from the libraries you chose. After doing this, the link tag will automatically be added by itself in dev and concatenated will other libs on prod for both angular pages and non angular pagescss_vendor_angular
: In this property you need to add the path to each new CSS file you want to add from the libraries you chose. After doing this, the link tag will automatically be added by itself in dev and concatenated will other libs on prod only for angular pagescss_vendor_non_angular
: In this property you need to add the path to each new CSS file you want to add from the libraries you chose. After doing this, the link tag will automatically be added by itself in dev and concatenated will other libs on prod only for NON angular pages
- Make watch only rebuild the part that's needed. If less is changed, then just change less, not everything.
- Use bower's
main
file to discover what file of the library to add instead of manually adding vendor files - Update to
gulp
- Separate CSS and JS files to have CSS on head and JS on body
The MIT License
Copyright (c) 2014 Martin Gontovnikas http://www.gon.to/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.