oncode / write-an-open-source-js-lib.md
The purpose of this document is to serve as a reference for:
Watch the series at egghead.io, if you haven’t.
- Introduction to How to Write an Open Source JavaScript Library
- Setting up GitHub
- Configuring npm and creating a package.json
- Creating the library and adding dependencies
- Pushing to GitHub
- Publishing to npm
- Releasing a version to GitHub
- Releasing a new version to npm
- Publishing a beta version
- Setting up Unit Testing with Mocha and Chai
- Unit Testing with Mocha and Chai
- Automating Releases with semantic-release
- Writing conventional commits with commitizen
- Committing a new feature with commitizen
- Automatically Releasing with TravisCI
- Automatically running tests before commits with ghooks
- Adding code coverage recording with Istanbul
- Adding code coverage checking
- Add code coverage reporting
- Adding badges to your README
- Adding ES6 Support
- Adding ES6 Support to Tests using Mocha and Babel
- Limit Built Branches on Travis
- Add a browser build to an npm module
Introduction to How to Write an Open Source JavaScript Library
- micro libraries
- pros
- small enough to reason about the code
- easy to test as there is less code
- easy to reuse via npm install
- managing dependencies as there could be too many
- create a Git repository
- host it on GitHub
- create the library
- publish it to npm
- create a full test suite for it using
- karma
- mocha
- chai
- create a GitHub account, if you don’t have one
- sign in to your account and create a new repository
- follow the instructions displayed after creating the repository, to push your code to that repository
- that’s all! GitHub setup is complete
Configuring npm and creating a package.json
- install node if not already installed
- configure npm locally to make publishing a little easier, for example
- $ npm set init-author-name «Sarbbottam Bandyopadhyay»
- $ npm set init-author-url «https://sarbbottam.github.io/»
- $ npm set init-author-email «sarbbottam@gmail.com»
- $ npm set init-license «MIT»
- $ cat ~/.npmrc
- save-exact property, it tells npm to use the exact version of the packages, rather than a version range, while saving dependency to package.json.
- it safeguards when semver is not followed properly or there’s a mistake in a release.
- enter username, password, and email when prompted
Creating the library and adding dependencies
- create the main file
- install required dependencies
- use -S or —save to save it as dependency at package.json
- use -D or —save-dev to save it as devDependency at package.json
- create a .gitignore at the root of the project, to list all the ignored files and directories
- $ git add to stage the changes
- alternatively $ git add —all to stage all the changes
- $ git remote -v will display all the available remote and their corresponding url
- $ npm add-user , if you have not already
- add package.json/files to whitelist the set of files to be published
- you can also add .npmignore file to ignore files/directories, that might fall under from whitelist
- $ npm version
, if you have already published to npm - patch for bug fix
- minor for new feature
- major for breaking changes
Releasing a version to GitHub
- add a version tag to git repository
- to associate the version released at npm to the corresponding code
- released to npm
- GitHub will consider the tag as release and will make it available under releases tab
- fill out the release form with the tag version
Releasing a new version to npm
- make necessary updates
- update the package.json/version $ npm version
- patch for bug fix
- minor for new feature
- major for breaking changes
Publishing a beta version
- make changes
- manually update the package version in package.json
- add -beta.0 to the end of the version
- $ npm info
Setting up Unit Testing with Mocha and Chai
- $ npm i -D mocha chai , to install and add them to devDependencies
- create a test file
- require(chai)
- require the file to be tested
var expect = require('chai').expect; var functionality = required('./path/to/index.js'); describe('functionality', function() it('should validate the functionality', function() expect(true).to.be.true; >); >);
Unit Testing with Mocha and Chai
- use the global describe function and it function to describe the tests and what they should do
- validate functionalities by assertions using expect
Automating Releases with semantic-release
- semantic-release automates the releasing and frees you from redundant manual steps.
- $ npm i -g semantic-release-cli to install semantic-release-cli globally
- $ semantic-release setup
- it will take you through the interactive prompt
- it will create a travis.yml if the CI system chosen, is travis.
- it will update package.json/script w.r.t release
- it will remove the version from package.json
- as the version will be determied dynamically from the commit messages
Writing conventional commits with commitizen
- commit message convention
- $ npm i -D commitizen cz-conventional-changelog
- install commitizen globally or add ./node_modules/bin to system PATH to use git cz instead of git commit
- alternatively you could use npm scripts , >
Committing a new feature with commitizen
- make changes to source and test
- use commitizen to commit with conventional message
- push the changes to GitHub
Automatically Releasing with TravisCI
- travis build is automatically setup by semantic-release
- if for some reason it is not enabled, manually sync github repo and enable travis build at https://travis-ci.org/profile/
- push a new version to npm
- push a new tag and release to github along with change history since the previous version
Automatically running tests before commits with ghooks
- $ npm i -D ghooks to install and add it to package.json/devDependencies
- configure ghooks via the > >
Adding code coverage recording with Istanbul
Adding code coverage checking
Add code coverage reporting
- signup for codecov.io
- $ npm i codecov.io -D
- create a script called report-coverage to report coverage to codecov.io.
- >
Adding badges to your README
- check out shields.io
- add badges via [![alt text](badge-url)](link to the service)
- for example: [![build](https://img.shields.io/travis//.svg)](https://travis-ci.org//)
- https://img.shields.io/. svg?style=flat-square
- need a transpiler to write code with latest JavaScript specs
- use babel
- $ npm i -D babel-cli to install and add it to package.json/devDependencies
- create a script called build to transpile ES6/ES2015 code to ES5
- >
- you can use -d instead of —out-dir
- use —copy-files to copy dependencies
- >
- >
- $ npm i -D rimraf to install and add it to package.json/devDependencies
- $ npm i -D babel-preset-es2015
- $ npm i -D babel-preset-stage-2
- checkout babel/pluglin for further details
- either in a .babelrc file or in package.json/babel
- .babelrc — $ echo ‘< "presets": ["es2015", "stage-2] >‘ > .babelrc
- package.json — < "babel" : < "presets": ["es2015", "stage-2] >>
Adding ES6 Support to Tests using Mocha and Babel
- npm i -D babel-register to install and add it to package.json/devDependencies
- pass babel-rgister as the compiler to mocha and update package.json/scripts.test
- ` >«
- ` >«
- >
Limit Built Branches on Travis
- only for whitelisting and exclude for blacklisting
- branch-name ( master ) could also be a regex
- travis will continue to build for pull requests
Add a browser build to an npm module
- $ npm i -D webpack
- create webpack.config.babel.js
- for example, checkout getting-started/#config-file
- $ npm i -D babel-loader
- -p for production build, minify the code
- $ npm i -D npm-run-all
- «build»: «npm-run-all build:*» to package.json/script
- pros