This time with a template engine, unit tests, integration tests, code coverage, continuous integration, code analysis and a nice setup flow.
$ npm install -g buster
$ npm install -g grunt
$ npm install -g istanbul
To run the server in development mode:
$ git clone https://github.com/5orenso/node-express-boilerplate.git
$ cd node-express-boilerplate
$ npm install
$ ./run-server.sh
This will restart the server every time a file has changed.
In addition to this I recommend using Grunt to watch your files and perform code analysis and run tests every time a file changes:
$ ./run-watch.sh
Running "watch" task
Waiting...
Now, go ahead and add modules into the ./app/routes/web.js or add more routes to the ./app/server.js file.
It’s safe to stop reading and start developing now :)
If you are up for the gory details please continue.
When you have setup a new stack you need to test the basics to see if your ideas are correct. I ran Apache Benchmark to see how this stack performs.
First let’s run the server as a single thread application:
node ./app/server.js -c config/config-dist.js
Results from single thread:
$ ab -n 10000 -c 100 'http://127.0.0.1:8000/index.html?foo=bar'
Document Path: /index.html?foo=bar
Document Length: 198 bytes
Concurrency Level: 100
Time taken for tests: 5.514 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 4030000 bytes
HTML transferred: 1980000 bytes
Requests per second: 1813.40 [#/sec] (mean)
Time per request: 55.145 [ms] (mean)
Time per request: 0.551 [ms] (mean, across all concurrent requests)
Transfer rate: 713.67 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 2
Processing: 19 55 16.7 50 111
Waiting: 18 55 16.7 50 111
Total: 21 55 16.7 50 111
Hmm, 1813 request/sec with a single thread. This is not bad, but still not great. Let’s test it as a cluster.
node ./app/server-cluster.js -c config/config-dist.js
Results from cluster mode:
$ ab -n 10000 -c 100 'http://127.0.0.1:8000/index.html?foo=bar'
Document Path: /index.html?foo=bar
Document Length: 198 bytes
Concurrency Level: 100
Time taken for tests: 2.621 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 3800000 bytes
HTML transferred: 1980000 bytes
Requests per second: 3815.84 [#/sec] (mean)
Time per request: 26.207 [ms] (mean)
Time per request: 0.262 [ms] (mean, across all concurrent requests)
Transfer rate: 1416.04 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 1.3 2 8
Processing: 1 24 24.9 17 242
Waiting: 1 23 24.8 16 241
Total: 2 26 24.6 18 243
So, 3815 requests/seq when running in cluster mode on my mac. This is not bad! So cluster is 2.1 times faster than a single thread.
---------- ----------- -------- ---------
| Internet | -> | server.js | -> | web.js | -> | date.js |
---------- ----------- -------- ---------
Contains application and a routes folder.
The main file for your server. This file also contains the binding between the URL and the route files.
A file to generate a Google sitemap.xml.
Folder for all your route files.
Main web routes file. Your route files handles all the requests from the web. It’s wise to separate all the routes in to different files based on the URLs. If you have a product section on your web page this should be represented with an own products route file and so on.
Config files. DO NOT CHECK IN PASSWORDS to Github.
Code coverage files after running ./report-code-coverage.sh
Application libraries.
Web logs
External node modules after running npm install
All frontend files such as html, css, robots.txt, etc.
All unit and integration tests.
Git ignore list.
JSHint config
Travis CI config.
Grunt config.
License
Documentation welcome file for Github.
npm package configuration.
Helper file for running code coverage analysis.
Helper file for running the server in dev mode.
Helper file for running unit tests.
Helper file for watching files while developing.