/ultimate-seed

{MEAN Stack on Steroids} The ultimate full-stack AngularJS + Node.js/Express seed (batteries included!) that makes web developers insanely productive. (Angular, AngularUI, Barbeque, Bootstrap, Bower, Browserify, Docker, Express, Font Awesome, Grunt, Handlebars, jQuery, JSHint, Karma/Mocha, LESS/LESSHat, Livereload, Lodash/Underscore, Modernizr, MongoDB/Mongoose, Passport for Facebook/Google/Twitter, Redis, SocketIO, Source Maps, Uglify, Winston)

Primary LanguageJavaScript

       _      _    _____   _   _       ____   _____   _____        ____   _____  _____  ____
      / \ /\ / \  /__ __\ / \ / \__/| /  _ \ /__ __\ /  __/       / ___\ /  __/ /  __/ /  _ \
      | | || | |    / \   | | | |\/|| | / \ |  / \   |  \  _____  |    \ |  \   |  \   | | \|
      | \_/| | |_/\ | |   | | | |  || | |-| |  | |   |  /_ \____\ \___ | |  /_  |  /_  | |_/|
      \____/ \____/ \_/   \_/ \_/  \| \_/ \ |  \_/   \____\       \____/ \____\ \____\ \____/

Screenshot Screenshot

Demo hosted on Heroku

ultimate-seed is the ultimate full-stack AngularJS + Node.js/Express seed (batteries included!) that makes web developers insanely productive.

This project uses ultimate dependency library.

Batteries Included

ultimate-seed comes with many of popular, battle-tested modern web frameworks and libraries. All these parts are already wired together for you using best practices! :) Don't waste time writing boilerplate code.

How to Use

Dependencies

Dependency Installation
Node.js download
MongoDB download
Redis download
Bower npm install bower -g
Grunt npm install grunt-cli -g

Make sure both MongoDB and Redis servers running somewhere. (You can use free hosting services such as MongoHQ or MongoLab for MongoDB and Redis To Go or RedisCloud for Redis.) Then, update configuration information in config/{development,production,staging}.json.

If you find any reason not to use Redis in your project, you can easily achieve it by following this instruction:

  1. Change the value of session.store._use to mongo in config/{development,production,staging}.json. (This lets ultimate-seed use MongoDB as session backend.)
  2. Comment out the line ultimate.db.redis.connect(app.config.db.redis); in server/app.js. (This prevents server connecting to Redis server.)

Installation

Method 1: Yeoman Generator

Yeoman generator for ultimate-seed can be used to clone the seed project.

$ npm install -g yo
$ npm install -g generator-ultimate
$ yo ultimate

Method 2: Git Clone

Download ultimate-seed and install dependency modules:

$ git clone https://github.com/pilwon/ultimate-seed.git ultimate-seed
$ cd ultimate-seed
$ npm install && bower install

Method 3: Git Branch Tracking Remote

Now create seed branch that tracks remote branch ultimate-seed/master:

$ git remote add seed https://github.com/pilwon/ultimate-seed.git
$ git fetch seed
$ git checkout -b seed seed/master

Merge seed to master branch by squashing commit log:

$ git checkout master
$ git merge seed
$ npm install && bower install

Resolve merge conflicts then push to origin/master:

$ git push

Development (config/development.json)

Grunt tasks to build your app:

$ grunt                    # start server
$ grunt build              # jshint & build
$ grunt clean              # clean generated files
  • If you see the Could not load the bindings file. error message, please perform npm rebuild then try again.

Testing

End-to-End (E2E) Testing with Protractor

Protractor wraps around WebDriverJS, which is a javascript binding for Selenium-Webdriver.

Selenium-Webdriver is a browser automation framework. Tests are written with the WebDriver API, which communicates with a Selenium server to control the browser under test. - Protractor Getting Started Guide

Therefore, you need to first download and install Selenium standalone server. If you successfully performed npm install, you will have ./node_modules/.bin/webdriver-manager. You can download and install Selenium standalone server by the following command:

$ ./node_modules/.bin/webdriver-manager update

From then on, you can start the server via:

$ ./node_modules/.bin/webdriver-manager start

You need to have the Selenium server running before running E2E tests. Once the Selenium server is running, you should also start the application server (in another tab) because your tests will run against it:

$ grunt

While the application server is running, open another tab and run e2e tests using Protractor.

$ grunt test

Enjoy watching your tests running inside a real browser (Chrome by default). If you'd like to change Protractor configuration, check out config/test/protractor-e2e.conf.js.

Deployment

Production/Staging Server (config/{production|stging}.json)

First, prepare and optimize all files used in production/staging environment:

$ grunt build

Then your app can be started in production/staging mode using this command:

$ NODE_ENV={production|staging} node server

It is recommended to use a tool like forever to ensure your app running continuously:

$ npm install forever -g
$ NODE_ENV={production|staging} PORT=3000 forever start server

You can alternatively use a system-wide process control system such as Supervisor with the following configuration (supervisord.conf):

[program:ultimate-3000]
directory = <absolute-path-of-project-root>
environment = NODE_ENV={production|staging}, PORT=3000
command = node server
autostart = true
autorestart = true

Heroku

ultimate-seed supports deployment of your app to Heroku servers.

  1. Modify config/heroku.json.
  2. Comment out the following lines in .gitignore. * /.cachebust * /client/js/node_modules/bower_components/ * /client-built/ * /config/heroku.json * /node_modules/
  3. Run grunt build to build the project.
  4. Commit all files to a local git repository created at the project root.
  5. Add git remote pointing to Heroku: * New Heroku app: heroku create APPID * Existing Heroku app: heroku git:remote -a APPID
  6. Set the environment variable: heroku config:set NODE_ENV={production|staging} ERROR_PAGE_URL=http://APPID.herokuapp.com/404.html
  7. Enable websocket support: heroku labs:enable websockets
  8. (Optional) Install MongoDB and Redis add-ons to the Heroku app. ultimate-seed reads environment variables attached by these add-ons. (Note: Add-on environment variables will override MongoDB/Redis configuration values in config/heroku.json): * Mongo: heroku addons:add mongohq:sandbox or heroku addons:add mongolab:sandbox * Redis: heroku addons:add redistogo:nano or heroku addons:add rediscloud:20
  9. Deploy application to Heroku using git push heroku +master
  10. Deployed at http://APPID.herokuapp.com/

Using Docker

  1. Install Docker.
  2. Download the seed project: git clone https://github.com/pilwon/ultimate-seed.git && cd $_
  3. Install dependencies: bower install && npm install
  4. Make code changes if desired.
  5. Build the project: grunt build
  6. Build Docker image: docker build -t ultimate-seed .
  7. Run redis and mongodb containers: - MongoDB: docker run -d --name mongodb dockerfile/mongodb - Redis: docker run -d --name redis dockerfile/redis
  8. Run the project container: CID=$(docker run -d -p 3000:80 --link redis:redis --link mongodb:mongodb ultimate-seed)
  9. Check logs: docker logs $CID
  10. Open in the browser: http://localhost:3000/

Using REPL (read-eval-print loop)

This is helpful when you need to debug problems on the production server. You can connect to REPL of the running server via UNIX socket. By default, it creates UNIX socket at /tmp/ultimate-repl.<PID> but you can configure it in config/{development,production,staging}.json. In order to connect to it, simply run:

$ nc -U /tmp/ultimate-repl.<PID>
ultimate>

or if you want readline's line editing and persistent history (i.e. using up/down arrow key to see the command history), then install rlwrap (on Mac, brew install rlwrap) and run:

$ rlwrap nc -U /tmp/ultimate-repl.<PID>
ultimate>

Once you are connected, you can evaluate Javascript expression.

ultimate> 3 + 3
6
ultimate>

For your convenience, several variables/functions are exposed. Try the followings:

ultimate> app  // ultimate app object
ultimate> ld  // lodash (underscore) object (couldn't use _ because it has special meaning in REPL i.e. the result of the last expression)
ultimate> ultimate  // ultimate object that ultimate-seed utilizes
ultimate> showRoutes()  // shows an array of all routes (e.g. [ ..., 'GET /api/user/features/:id', ...])

Directory Structure

.
├── client/
│   ├── components/
│   ├── fonts/
│   │   ├── font-awesome/
│   │   └── glyphicons/
│   ├── js/
│   │   ├── {{module}}/
│   │   │   ├── controllers/
│   │   │   ├── directives/
│   │   │   ├── services/
│   │   │   ├── templates/
│   │   │   │   └── {{template}}.html
│   │   │   └── index.js
│   │   ├── node_modules/
│   │   │   ├── bower_components/
│   │   │   └── custom_components/
│   │   ├── app.js
│   │   └── index.js
│   └── less/
│       ├── _layouts/
│       ├── bootstrap/
│       ├── font-awesome/
│       ├── lesshat/
│       └── social-buttons/
├── config/
│   ├── server/
│   │   └── nginx.conf
│   ├── test/
│   │   ├── karma-e2e.conf.js
│   │   ├── karma-unit.conf.js
│   │   └── protractor-e2e.conf.js
│   ├── development.json
│   ├── production.json
│   └── staging.json
├── log/
├── node_modules/
├── server/
│   ├── controllers/
│   ├── lib/
│   ├── models/
│   ├── sockets/
│   ├── views/
│   │   ├── _helpers/
│   │   ├── _layouts/
│   │   │   └── default.hbs
│   │   ├── _partials/
│   │   │   └── livereload.hbs
│   │   ├── home/
│   │   ├── status/
│   │   └── empty.hbs
│   ├── app.js
│   ├── index.js
│   ├── routes.js
│   ├── socketio.js
│   └── winston.js
├── static/
│   ├── img/
│   ├── 404.html
│   ├── favicon.ico
│   └── robots.txt
├── worker/
│   ├── task/
│   ├── index.js
│   └── process.js
├── .bowerrc
├── .editorconfig
├── .jshintrc
├── .slugignore
├── Gruntfile.js
├── Procfile
├── bower.json
├── npm-scripts.js
├── package.json
└── project.json

FAQ

How do I fix the error EMFILE: Too many opened files.?

This is an issue with grunt-contrib-watch. You can fix it by increasing your system's max opened file limit. See this answer NOTE: Even if ulimit command on the shell gives you 'unlimited', you might still need to increase the max opened file limit.

How do I fix Error: Could not load the bindings file.?

If you are using node version manager n, you might come across the following error message when running grunt:

  Fatal error: Server ["/Users/username/path-to-ultimate-seed/server"] -  Error: Could not load the bindings file. Tried:
→ /Users/username/path-to-ultimate-seed/node_modules/bcrypt/build/bcrypt_lib.node
→ /Users/username/path-to-ultimate-seed/node_modules/bcrypt/build/Debug/bcrypt_lib.node
...
→ /Users/username/path-to-ultimate-seed/node_modules/bcrypt/build/default/bcrypt_lib.node
→ /Users/username/path-to-ultimate-seed/node_modules/bcrypt/compiled/0.10.23/darwin/x64/bcrypt_lib.node

In order to fix it, run npm rebuild. Then you will be able to run grunt without seeing the above error message.

Contributing to the Project

We welcome your pull requests to the dev branch.

Credits

Thanks to all the other contributors as well! :)

License

The MIT License (MIT)

Copyright (c) 2012-2014 Pilwon Huh

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.

Analytics