…or actually…
How to create and publish a node package using JSHint and JSCS for linting, Mocha for testing, Istanbul for code coverage, GitHub for hosting and Travis for continuous integration including Code Climate support and auto-deploy to npm registry.
We are going to create a project structure like this:
my-awesome-module/
├─╸ .git/
├─╸ coverage/
├─╸ lib/
│ └─╸ index.js
├─╸ node_modules/
├─╸ test/
│ └─╸ index.js
├─╸ .editorconfig
├─╸ .gitignore
├─╸ .jscsrc
├─╸ .jshintrc
├─╸ .travis.yml
├─╸ package.json
└─╸ README.md
Run:
mkdir -p lib test && touch lib/index.js test/index.js .editorconfig .gitignore .jscsrc .jshintrc .travis.yml package.json README.md
Create a repo on GitHub, initialize you local repo and add the remote.
git init
git remote add origin git://github.com/<USER>/<REPO>.git
That's where we put our code. The main file should be index.js
and contain
something like this:
'use strict';
module.exports = function() {
return true;
};
See Node.js modules docs.
…should look like this:
{
"name": "my-awesome-module",
"description": "Description goes here.",
"keywords": ["some", "related", "things"],
"author": "Foo Bar <[email protected]> (http://foobar.com)",
"license": "MIT",
"version": "0.1.0",
"repository": {
"type" : "git",
"url" : "git://github.com/<USER>/<REPO>.git"
},
"bugs": "https://github.com/<USER>/<REPO>/issues",
"main": "lib/index.js",
"files": [],
"os" : ["darwin", "linux"],
"engines" : {
"node" : ">=0.11.10",
"npm": ">=1.3.22"
},
"scripts": {
"test": "mocha -R spec",
"lint": "jshint ./lib/*.js & jscs ./lib/*.js",
"cover": "istanbul cover ./node_modules/.bin/_mocha -- -R spec",
"watch": "mocha -R spec -w",
"codeclimate": "codeclimate-test-reporter < coverage/lcov.info"
}
}
See package.json docs.
name
your package wisely!
And as you hopefully know what you want to achieve, you don't need much time to
think of a good description
and keywords
.
Your package's version
number should stick to SemVer and
start initially with 0.1.0
.
files
should contain all additional files or folders that should be included
in our final package. The main
file and the readme are included automatically
(and in most cases no other includes are needed).
Ensure that your module works with defined os
and engines
.
We already defined some scripts
in your package.json
, now you need to
install the testing and linting tools and save them as devDependencies
:
npm install --save-dev mocha istanbul jshint jscs codeclimate-test-reporter
If your final module has other modules as direct dependencies, they should be
installed and saved as dependencies
, so you can require()
them as usual:
npm install --save some-other-module
Add your tests to lib/index.js
:
'use strict';
var assert = require('assert'),
pkgJson = require('../package.json'),
pkgName = pkgJson.name,
pkg = require('..');
describe(pkgName, function() {
it('should return true', function() {
assert.equal(pkg(), true);
});
});
Now you can run them via npm run test
or watch and test on change using npm run watch
.
Code coverage reports can be found in coverage/
after running npm run cover
.
JSHint options are set via .jshintrc
.
See JSHint options docs
and example .jshintrc
.
{
"node": true,
"globals": {
"describe": true,
"it": true
},
"strict": true,
"undef": true,
"unused": true,
"validthis": true,
"maxcomplexity": 5
}
Same thing for JSCS and .jscsrc
.
See JSCS rules docs.
{
"preset": "google",
"validateIndentation": 4,
"disallowMultipleVarDecl": null,
"maximumLineLength": 120
}
Our package's code can now be linted via npm run lint
.
You should setup your IDE to lint code automatically using option files in the project folder:
-
with Sublime Text 3: SublimeLinter, JSHint, JSCS
Install Travis command line client.
Run travis login && travis init
within your project root.
Your .travis.yml
should look like this:
language: node_js
node_js:
- '0.12'
- '0.11.10'
Go to your Travis CI profile and make sure Travis support is activated for your project's GitHub repository.
Assuming you have an npm account, you need to get your npm api key now.
After running npm adduser
and npm login
you should find an entry liky this
in your local ~/.npmrc
:
registry.npmjs.org/:_authToken=THIS-IS-YOUR-API-KEY
Add the following lines to your .travis.yml
, replacing email and repo path:
deploy:
provider: npm
email: [email protected]
api_key: ${NPM_API_KEY}
on:
tags: true
repo: <USER>/<REPO>
Add and encrypt NPM_API_KEY
as global environment var:
travis encrypt NPM_API_KEY=PASTE-YOUR-API-KEY-HERE --add env.global
By using the api key via environment variable and not directly as value of
deploy.api_key
, we can reuse it later, i.e. for Code Climate exports.
Add your repo to Code Climate then
navigate to <REPO> / Settings / Test Coverage
and find a line like this:
CODECLIMATE_REPO_TOKEN=YOUR-CUSTOM-REPO-TOKEN
Copy that part and add it as encrypted gloval environment variable to your
.travis.yml
:
travis encrypt CODECLIMATE_REPO_TOKEN=YOUR-CUSTOM-REPO-TOKEN --add env.global
Also add the following lines to your .travis.yml
to run coverage generation
and Code Climate reports after a build:
after_script:
- npm run cover
- npm run codeclimate
…should at least contain:
/coverage
/node_modules
npm-debug.log
Keep consistency.
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[{*.md,*.markdown}]
trim_trailing_whitespace = false
[{*.json,*.yml,*.js*rc}]
indent_size = 2
…could contain some proud badges and look like this:
my-awesome-module
=================
> Description goes here.
[](https://www.npmjs.com/package/NAME)
[](http://USER.mit-license.org)
[](https://david-dm.org/USER/NAME)
[](https://david-dm.org/USER/NAME#info=devDependencies)
[](https://travis-ci.org/USER/NAME)
[](https://codeclimate.com/github/USER/NAME)
[](https://codeclimate.com/github/USER/NAME)
---
## Install
npm install my-awesome-module
## Usage
var myAwesomeModule = require('my-awesome-module')();
## License
[MIT](http://USER.mit-license.org/)
After updating the version
value in your package.json
and committing all
changes, tag your latest commit and push with tags to origin:
git tag -a 0.1.0 -m ""
git push origin --tags
Travis will be triggered and if the build is successful, your package and its test and coverage reports will be automatically published.