This repository contains build and test automation for JavaScript applications. It's intended as a starting point for your own JavaScript projects. It's best for standalone applications, not npm modules. It includes:
- Automated build (using Jake) with:
- Linting (using JSHint)
- Node.js tests (using Mocha)
- Cross-browser tests (using Karma, Mocha, and expect.js)
- Front-end modules (using Browserify)
- Automated continuous integration (using Git)
- Automated deployment (to Heroku)
- Example code (in the
src
directory):- Server-side integration test
- Development smoke test
- Release smoke test
- Client-side DOM test
This code was originally developed for James Shore's Let's Code: Test-Driven JavaScript screencast. See Lessons Learned #16, JavaScript Workflow 2015, for a detailed description of the front-end and continuous integration workflow.
You may wonder why this repository includes dependencies (in node_modules
) and IDE settings (in .idea
). The reasoning is explained in my essay, "The Reliable Build." If you prefer not to include these sorts of things in your repo, it's fine to remove them.
Change History:
- 21 Sep 2016: Latest npm dependencies; Node LTS v4.5.0
- 13 Jun 2016: Latest npm dependencies; Node LTS v4.4.5
- 22 Jan 2015: Front-end modules;
watch
script; improved documentation;jake run
; latest npm dependencies; integration commit messages; general script improvements - 29 Jul 2014: Replaced NodeUnit with Mocha; updated npm dependencies to latest versions; documented process for installing npm packages; replaced JSHint runner with simplebuild-jshint module
- 22 Dec 2013: Removed unneeded Karma plugins; cleaned up package.json; updated npm dependencies to latest versions
- 24 Sep 2013: Upgraded to Karma 0.10 (also updated all other npm dependencies to latest versions)
- 30 Nov 2012: Initial release
Start out by downloading the code as described in "Download and Setup," below. Then:
-
If you're a solo developer using this repository as a starting point for a personal project, follow the steps under "Building and Testing."
-
If you're part of a team and planning to use the continuous integration script, follow the steps under "Continuous Integration." (If you don't plan to use the CI script, follow the steps under "Building and Testing" and supply your own CI tool.)
-
If you're part of a team and planning to use the Heroku deployment script, follow the steps under "Deploying to Heroku." Note that the deployment script assumes you're also using the CI script.
Once you have it working, delete anything you don't need and modify anything you like. Make it your own.
This repository consists of the following directories:
.idea
: WebStorm IDE settings. (Optional.)build
: Build, CI, and deployment automation.build/config
: Build configuration.build/scripts
: Build scripts. Don't run them directly; they're used by the scripts in the root directory.build/util
: Modules used by the build scripts.node_modules
: npm dependencies. (Optional. See "Installing, Updating, and Removing npm Packages" below.)src
: Example code.src/client
: Front-end code.src/server
: Node.js server code.
In the repository root, you'll find the following scripts. For each script, there's a .sh
version for Unix and Mac and a .bat
version for Windows:
ci
: Continuous integration automation.deploy
: Automated deployment to Heroku.jake
: Build and test automation.watch
: Automatically runsjake
when any files change. Any arguments are passed through to jake.
For all these scripts, use -T
to see the available build targets and their documentation. If no target is provided, the script will run default
. Use --help
for additional options.
The jake
script has this additional option:
loose=true
: Disable strict browser and version checks.
To download the project:
- Install Git.
- Clone the latest code only (to save time):
git clone --depth 1 https://github.com/jamesshore/automatopia.git
- Modify
package.json
to use your Node version in theengines.node
line. (Runnode --version
to determine your Node version.) - Delete the
.git
directory so you start fresh - Run
git init
,git add .
, andgit commit -am "Initial commit"
to initialize the git repository. - Follow the instructions under "Building and Testing" to make sure everything works.
(Note: You can also download a zip file of the source code, but that won't preserve permissions like Git does.)
To customize the project for your needs:
- Modify
LICENSE.TXT
to contain your copyright and license. - To cause the build to fail unless certain browsers are tested, edit
build/config/tested_browsers.js
. Otherwise, comment those lines out.
This repository assumes you check your npm modules into git. (Why? See here.) Some modules come pre-installed. To update those packages, or install new ones, use the following process to ensure that you don't check in binaries:
- Install the package without building it:
npm install <package> --ignore-scripts --save-dev
(or--save
instead of--save-dev
) - Check in the new module:
git add . && git commit -a
- Build the package:
npm rebuild
- Check for files created by the npm build:
git status
- Add any new files from the previous step to the
.gitignore
file and check it in.
To update all npm dependencies at once:
- Delete the
node_modules
directory. - Modify
.gitignore
and remove all references to npm module binaries. - Install dependencies without building them:
npm install --ignore-scripts
- Check everything in:
git add . && git commit -am "Updated npm dependencies"
- Rebuild everything:
npm rebuild
- Check for files created by the npm build:
git status
- Add any new files from the previous step to the
.gitignore
file and check it in.
If you would rather not check your npm modules into git, you can remove them like this:
- Delete the node_modules directory.
- Modify
.gitignore
and replace the references to npm module binaries withnode_modules/
. - Modify
build/scripts/run_jake.sh
andbuild/scripts/run_jake.bat
to saynpm install
instead ofnpm rebuild
. - Check everything in:
git add . && git commit -am "Removed node_modules"
.
This project tests front-end code inside real browsers using a tool called Karma. When you start your work day, you'll start the Karma server and the test browsers, then use a different command prompt to run the tests.
Some browsers are designed to de-prioritize JavaScript if the associated tab isn't visible on-screen. If your tests run very slowly, make sure the Karma tab is selected and visible (not covered up by other windows) in every browser.
Before building for the first time:
- Install Node.js.
- Download the project as described above.
- All commands must run from the root of the source tree.
To build (and test):
- Run
./jake.sh karma
(Unix/Mac) orjake karma
(Windows) to start the Karma server. - Start the browsers you want to test and point each one at
http://localhost:9876
. - Run
./jake.sh
(Unix/Mac) orjake
(Windows) every time you want to build and test. Alternatively, use./watch.sh
(Unix/Mac) orwatch
(Windows) to automatically runjake
whenever files change.
Add the loose=true
parameter to relax Node and browser version checking.
To run the app for manual testing:
- Run
./jake.sh run
(Unix/Mac) orjake run
(Windows).
To set up continuous integration for a team of developers:
- Choose a machine to be the integration machine.
- Follow the steps for "Building and Testing" on the integration machine.
- Run
git checkout -b integration
to create and checkout the integration branch.
To set up each development workstation:
- Choose an easy-to-type name for the development workstation, such as
dev1
. Put a label on the machine with this name so you don't forget it--you'll use it when you integrate. - On the integration machine, run
git branch <name>
to create a branch for the development workstation. - Clone the integration machine's repository to the development workstation. (The steps here depend on your network configuration. Talk to your local Git expert.)
- On the development workstation, run
git checkout <name>
to switch to the development branch. - Now you can build and test as described above.
To integrate:
- Run
./ci.sh usage
(Unix/Mac) orci usage
(Windows) for instructions.
Before deploying for the first time:
- Follow the steps for "Continuous Integration" first.
- Sign up for a Heroku account.
- On the integration machine, install the Heroku Toolbelt.
- Create a Heroku application:
heroku create <app_name>
. If you've already created the application, you can reconnect to it withheroku git:remote --app <app_name>
. - On a development machine, change
PRODUCTION_URL
at the top ofbuild/scripts/deploy.jakefile
tohttp://<app_name>.herokuapp.com
. - Update the
engines
section ofpackage.json
to match your installed versions of Node and npm. (Usenode --version
andnpm --version
to get the version numbers.) - Integrate as described above.
To deploy:
- On the integration machine, run
./deploy.sh latest
(Unix/Mac) ordeploy latest
(Windows) to deploy the integration branch to Heroku. The script will tag your git repository withdeploy-<timestamp>
if the deploy succeeds and passes the smoke tests.
In case of a bad deployment:
- On the integration machine, run
./deploy.sh rollback
(Unix/Mac) ordeploy rollback
(Windows) to do a band-aid rollback to the previous Heroku deployment. This rollback won't "stick", so you'll need to deploy new code soon. - If you aren't able to deploy new code right away, choose a previous, good commit to deploy.
gitk
and thedeploy-<timestamp>
tags may be helpful here. - Check out the commit:
git checkout <commit_id>
- Run
./deploy.sh head
(Unix/Mac) ordeploy head
(Windows) to deploy the commit to Heroku. As above, the script will tag the git repository withdeploy-<timestamp>
if the deploy succeeds and passes the smoke tests.
MIT License. See LICENSE.TXT
.