├── .gitignore ├── license └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | # OS generated files # 2 | ###################### 3 | .DS_Store 4 | .DS_Store? 5 | ._* 6 | .Spotlight-V100 7 | .Trashes 8 | ehthumbs.db 9 | Thumbs.db 10 | 11 | # Test # 12 | ######## 13 | coverage 14 | test-results.xml 15 | 16 | # Generated files # 17 | ################### 18 | out 19 | dist 20 | example/main.js 21 | 22 | # Node # 23 | ######## 24 | node_modules 25 | 26 | # Logs and databases # 27 | ###################### 28 | logs 29 | *.log 30 | *.sql 31 | *.sqlite 32 | 33 | # Packages # 34 | ############ 35 | *.7z 36 | *.dmg 37 | *.gz 38 | *.iso 39 | *.jar 40 | *.rar 41 | *.tar 42 | *.zip 43 | 44 | # Runtime data # 45 | ################ 46 | pids 47 | *.pid 48 | *.seed 49 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Sarbbottam Bandyopadhyay 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Reference for [How to Write an Open Source JavaScript Library](https://egghead.io/series/how-to-write-an-open-source-javascript-library) 2 | --- 3 | 4 | The purpose of this document is to serve as a reference for: 5 | 6 | [How to Write an Open Source JavaScript Library](https://egghead.io/series/how-to-write-an-open-source-javascript-library) course by [Kent C. Dodds](https://github.com/kentcdodds) 7 | 8 | Watch the series at [egghead.io](https://egghead.io/series/how-to-write-an-open-source-javascript-library), if you haven't. 9 | 10 | --- 11 | 12 | 13 | 14 | 15 | 16 | - [Introduction to How to Write an Open Source JavaScript Library](#introduction-to-how-to-write-an-open-source-javascript-library) 17 | - [Setting up GitHub](#setting-up-github) 18 | - [Configuring npm and creating a package.json](#configuring-npm-and-creating-a-packagejson) 19 | - [Creating the library and adding dependencies](#creating-the-library-and-adding-dependencies) 20 | - [Pushing to GitHub](#pushing-to-github) 21 | - [Publishing to npm](#publishing-to-npm) 22 | - [Releasing a version to GitHub](#releasing-a-version-to-github) 23 | - [Releasing a new version to npm](#releasing-a-new-version-to-npm) 24 | - [Publishing a beta version](#publishing-a-beta-version) 25 | - [Setting up Unit Testing with Mocha and Chai](#setting-up-unit-testing-with-mocha-and-chai) 26 | - [Unit Testing with Mocha and Chai](#unit-testing-with-mocha-and-chai) 27 | - [Automating Releases with semantic-release](#automating-releases-with-semantic-release) 28 | - [Writing conventional commits with commitizen](#writing-conventional-commits-with-commitizen) 29 | - [Committing a new feature with commitizen](#committing-a-new-feature-with-commitizen) 30 | - [Automatically Releasing with TravisCI](#automatically-releasing-with-travisci) 31 | - [Automatically running tests before commits with ghooks](#automatically-running-tests-before-commits-with-ghooks) 32 | - [Adding code coverage recording with Istanbul](#adding-code-coverage-recording-with-istanbul) 33 | - [Adding code coverage checking](#adding-code-coverage-checking) 34 | - [Add code coverage reporting](#add-code-coverage-reporting) 35 | - [Adding badges to your README](#adding-badges-to-your-readme) 36 | - [Adding ES6 Support](#adding-es6-support) 37 | - [Adding ES6 Support to Tests using Mocha and Babel](#adding-es6-support-to-tests-using-mocha-and-babel) 38 | - [Limit Built Branches on Travis](#limit-built-branches-on-travis) 39 | - [Add a browser build to an npm module](#add-a-browser-build-to-an-npm-module) 40 | 41 | 42 | 43 | --- 44 | 45 | ## Introduction to How to Write an Open Source JavaScript Library 46 | 47 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-introduction) 48 | - micro libraries 49 | - pros 50 | - small enough to reason about the code 51 | - easy to test as there is less code 52 | - easy to reuse via `npm install` 53 | - cons 54 | - managing dependencies as there could be too many 55 | 56 | - objective of the course / learn to 57 | - create a Git repository 58 | - host it on GitHub 59 | - create the library 60 | - publish it to npm 61 | - create a full test suite for it using 62 | - karma 63 | - mocha 64 | - chai 65 | - set up continuous integration 66 | - add ES6 or ES2015 using Babel 67 | - integrate webpack 68 | - distribute this as both browser and node consumable 69 | 70 | ## Setting up GitHub 71 | 72 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-setting-up-github) 73 | - create a GitHub account, if you don't have one 74 | - sign in to your account and create a new repository 75 | - follow the instructions displayed after creating the repository, to push your code to that repository 76 | - that's all! GitHub setup is complete 77 | 78 | ## Configuring npm and creating a package.json 79 | 80 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-configuring-npm-and-creating-a-package-json) 81 | - install node if not already installed 82 | - configure npm locally to make publishing a little easier, for example 83 | - `$ npm set init-author-name "Sarbbottam Bandyopadhyay"` 84 | - `$ npm set init-author-url "https://sarbbottam.github.io/"` 85 | - `$ npm set init-author-email "sarbbottam@gmail.com"` 86 | - `$ npm set init-license "MIT"` 87 | - these will be used as defaults values during `npm init` 88 | - verify configuration 89 | - `$ cat ~/.npmrc` 90 | - refer https://docs.npmjs.com/misc/config for more information 91 | - recommended setting 92 | - `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. 93 | - it safeguards when semver is not followed properly or there's a mistake in a release. 94 | - create a npm account, if you don't have one at [npmjs.com](https://www.npmjs.com/) 95 | - `$ npm add-user`, to add your account 96 | - enter username, password, and email when prompted 97 | - it will create your `auth token` and add it to `~/.npmrc` 98 | - `$ npm init` will prompt for desired information and create `package.json` at the end 99 | - `$ npm init --yes` will create a `package.json`, with the defaults, with out prompting 100 | 101 | ## Creating the library and adding dependencies 102 | 103 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-creating-the-library-and-adding-dependencies) 104 | - create the `main` file 105 | - install required dependencies 106 | - use `-S` or `--save` to save it as `dependency` at `package.json` 107 | - use `-D` or `--save-dev` to save it as `devDependency` at `package.json` 108 | - create the functionality 109 | 110 | ## Pushing to GitHub 111 | 112 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-pushing-to-github) 113 | - create a `.gitignore` at the `root` of the project, to list all the ignored files and directories 114 | - `$ git add ` to stage the changes 115 | - alternatively [`$ git add --all`](https://github.com/sarbbottam/conf-files/blob/master/git-confs/gitconfig#L20) to stage all the changes 116 | - `$ git commit` to commit the changes 117 | - `$ git push origin ` to push the changes to GitHub(`origin`) 118 | - `$ git remote -v` will display all the available `remote` and their corresponding `url` 119 | 120 | ## Publishing to npm 121 | 122 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-publishing-to-npm) 123 | - `$ npm add-user`, if you have not already 124 | - add `package.json/files` to [whitelist the set of files to be published](https://docs.npmjs.com/files/package.json#files) 125 | - you can also add `.npmignore` file to ignore files/directories, that might fall under from whitelist 126 | - `$ npm version `, if you have already published to npm 127 | - `patch` for bug fix 128 | - `minor` for new feature 129 | - `major` for breaking changes 130 | - [`npm pack`](https://docs.npmjs.com/cli/pack) or [`npm link`](https://docs.npmjs.com/cli/link) to validate the module to be publish 131 | - `$ npm publish` 132 | - verify the released package at `npm.im/` 133 | 134 | ## Releasing a version to GitHub 135 | 136 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-releasing-a-version-to-github) 137 | - add a version tag to git repository 138 | - to associate the version released at npm to the corresponding code 139 | - `tag` in git, points to a specific commit 140 | - `$ git tag ` 141 | - `` released to npm 142 | - `$ git push --tags` 143 | - GitHub will consider the tag as release and will make it available under `releases` tab 144 | - draft new release 145 | - fill out the release form with the tag version 146 | 147 | ## Releasing a new version to npm 148 | 149 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-releasing-a-new-version-to-npm) 150 | - make necessary updates 151 | - update the `package.json/version` `$ npm version ` 152 | - `patch` for bug fix 153 | - `minor` for new feature 154 | - `major` for breaking changes 155 | - `commit` the changes 156 | - `tag` the commit. 157 | - push changes to GitHub 158 | - push the tags to GitHub 159 | - `$ npm publish` 160 | 161 | ## Publishing a beta version 162 | 163 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-publishing-a-beta-version) 164 | - make changes 165 | - manually update the package version in `package.json` 166 | - add `-beta.0` to the end of the version 167 | - `$ git checkout -b ` for the beta version 168 | - `$ git tag ` 169 | - `$ git push origin ` 170 | - `$ git push --tags` 171 | - `$ npm publish --tag beta` 172 | - verify published versions 173 | - `$ npm info` 174 | 175 | ## Setting up Unit Testing with Mocha and Chai 176 | 177 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-setting-up-unit-testing-with-mocha-and-chai) 178 | - `$ npm i -D mocha chai`, to install and add them to `devDependencies` 179 | - create a test file 180 | - `require(chai)` 181 | - `require` the file to be tested 182 | 183 | ```js 184 | var expect = require('chai').expect; 185 | var functionality = required('./path/to/index.js'); 186 | 187 | describe('functionality', function() { 188 | it('should validate the functionality', function() { 189 | expect(true).to.be.true; 190 | }); 191 | }); 192 | ``` 193 | - update `package.json/script.test` 194 | - `{"scripts": { "test": "mocha path/to/test/file" } }` 195 | - add `-w` to watch for changes 196 | - `$ npm test` to run test 197 | 198 | ## Unit Testing with Mocha and Chai 199 | 200 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-unit-testing-with-mocha-and-chai) 201 | - use the `global` `describe` function and `it` function to describe the tests and what they should do 202 | - validate functionalities by assertions using `expect` 203 | 204 | ## Automating Releases with semantic-release 205 | 206 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-automating-releases-with-semantic-release) 207 | - `semantic-release` automates the releasing and frees you from redundant manual steps. 208 | - `$ npm i -g semantic-release-cli` to install `semantic-release-cli` globally 209 | - `$ semantic-release setup` 210 | - it will take you through the interactive prompt 211 | - it will create a `travis.yml` if the CI system chosen, is travis. 212 | - it will update `package.json/script` w.r.t `release` 213 | - it will remove the `version` from `package.json` 214 | - as the version will be determined dynamically from the commit messages 215 | - this `script` will be executed on `success` 216 | - update `travis.yml` to run tests prior releasing 217 | - update the `package.json/version` to `0.0.0-sematically-released`, to avoid `npm` warning 218 | 219 | ## Writing conventional commits with commitizen 220 | 221 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-writing-conventional-commits-with-commitizen) 222 | - commit message [convention](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#-git-commit-guidelines) 223 | - `$ npm i -D commitizen cz-conventional-changelog` 224 | - install `commitizen` globally or add `./node_modules/bin` to system `PATH` [to use `git cz` instead of `git commit`](https://github.com/commitizen/cz-cli#installing-the-command-line-tool) 225 | - alternatively you could use `npm scripts`, `{"scripts": { "commit": "git-cz" } }` 226 | - [configure `commitizen`](https://github.com/commitizen/cz-cli#making-your-repo-commitizen-friendly) via `{config": { "commitizen": { "path": "cz-conventional-changelog" } } }` 227 | 228 | ## Committing a new feature with commitizen 229 | 230 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-committing-a-new-feature-with-commitizen) 231 | - make changes to `source` and `test` 232 | - use `commitizen` to commit with conventional message 233 | - push the changes to GitHub 234 | 235 | ## Automatically Releasing with TravisCI 236 | 237 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-automatically-releasing-with-travisci) 238 | - travis build is automatically setup by semantic-release 239 | - if for some reason it is not enabled, manually sync github repo and enable travis build at `https://travis-ci.org/profile/` 240 | - if the build is successful, travis will run `semantic-release` 241 | - depending on the commit messages, `semantic-release` would 242 | - push a new version to npm 243 | - push a new tag and release to github along with change history since the previous version 244 | 245 | ## Automatically running tests before commits with ghooks 246 | 247 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-automatically-running-tests-before-commits-with-ghooks) 248 | - `$ npm i -D ghooks` to install and add it to `package.json/devDependencies` 249 | - configure `ghooks` via the `{"config": {"ghooks": { "hook-name": "command-to-execute" } } }` 250 | 251 | ## Adding code coverage recording with Istanbul 252 | 253 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-adding-code-coverage-recording-with-istanbul) 254 | - `$ npm i istanbul` 255 | - update `package.json/script.test` 256 | - `{"scripts": { "test": "istanbul cover -x test-file-name-pattern _mocha -- path/to/test/file -R spec" } }` 257 | - `$ npm test` will run the test and generate coverage information at `coverage/` folder 258 | - add `coverage` to `.gitignore` file 259 | 260 | ## Adding code coverage checking 261 | 262 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-adding-code-coverage-checking) 263 | - create a script called `check-coverage` to verify coverage for statements, branches, functions, and lines. 264 | - `{"scripts": { "check-coverage": "istanbul check-coverage --statement 100 --branches 100 --function 100 --lines 100" } }` 265 | - add `npm run check-coverage` to `travis/script` 266 | - you can also add it to `git hooks` 267 | - `{"config": {"ghooks": { "pre-commit": "npm test && npm run check-coverage" } } }` 268 | 269 | ## Add code coverage reporting 270 | 271 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-add-code-coverage-reporting) 272 | - signup for [codecov.io](https://codecov.io/) 273 | - `$ npm i codecov.io -D` 274 | - create a script called `report-coverage` to report coverage to [codecov.io](https://codecov.io/). 275 | - `{"scripts": { "report-coverage": "cat ./coverage/lcov.info | codecov" } }` 276 | - add `npm run report-coverage` to `travis/after_success` 277 | - after successful build the reports will be pushed to [`codecov.io/github//`](https://codecov.io/) 278 | - check out [codecov browser extension](https://www.youtube.com/watch?v=d6wJKODB8_g&feature=youtu.be) 279 | 280 | ## Adding badges to your README 281 | 282 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-adding-badges-to-your-readme) 283 | - check out [shields.io](http://shields.io/) 284 | - add badges via `[![alt text](badge-url)](link to the service)` 285 | - for example: `[![build](https://img.shields.io/travis//.svg)](https://travis-ci.org//)` 286 | - you can also pass the `style` query param to customize the style of the badge 287 | - `https://img.shields.io/...svg?style=flat-square` 288 | 289 | ## Adding ES6 Support 290 | 291 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-adding-es6-support) 292 | - need a transpiler to write code with latest JavaScript specs 293 | - use [babel](http://babeljs.io/) 294 | - `$ npm i -D babel-cli` to install and add it to `package.json/devDependencies` 295 | - create a script called `build` to transpile ES6/ES2015 code to ES5 296 | - `{"scripts": { "build": "babel --out-dir dist src" } }` 297 | - you can use `-d` instead of `--out-dir` 298 | - use `--copy-files` to copy dependencies 299 | - `{"scripts": { "build": "babel --copy-files --out-dir dist src" } }` 300 | - checkout [babel/setup/cli](http://babeljs.io/docs/setup/#cli) for further details 301 | - add a script called `prebuild` to clean the `dist` directory prior building 302 | - `{"scripts": { "prebuild": "rimraf dist" } }` 303 | - `$ npm i -D rimraf` to install and add it to `package.json/devDependencies` 304 | - install desired babel presets/plugin and add it to `package.json/devDependencies` 305 | - `$ npm i -D babel-preset-es2015` 306 | - `$ npm i -D babel-preset-stage-2` 307 | - checkout [babel/pluglin](http://babeljs.io/docs/plugins/) for further details 308 | - create babel config 309 | - either in a `.babelrc` file or in `package.json/babel` 310 | - `.babelrc` - `$ echo '{ "presets": ["es2015", "stage-2] }' > .babelrc` 311 | - `package.json` - `{ "babel" : { "presets": ["es2015", "stage-2] } }` 312 | - `$ npm run build` will create the transpiled code in `dist` folder 313 | - update `package.json/main` to refer `dist` 314 | - add `npm run build` to `travis.yml/script` 315 | - add `dist/` to `.gitignore` 316 | 317 | ## Adding ES6 Support to Tests using Mocha and Babel 318 | 319 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-adding-es6-support-to-tests-using-mocha-and-babel) 320 | - `npm i -D babel-register` to install and add it to `package.json/devDependencies` 321 | - pass `babel-rgister` as the compiler to `mocha` and update `package.json/scripts.test` 322 | - `{"scripts": { "test": "mocha path/to/test/file --compilers js:babel-register" } }`` 323 | - `$ npm i -d nyc` to install and add it to `package.json/devDependencies` 324 | - add a script called `cover` 325 | - `{"scripts": { "cover": "nyc npm test" } }`` 326 | - update `ghook` and `travis/script` run `npm run cover` instead of `npm test` 327 | - replace `istanbul` with `nyc` at `package.json/scripts.check-coverage` 328 | - `{"scripts": { "check-coverage": "nyc check-coverage --statement 100 --branches 100 --function 100 --lines 100" } }` 329 | - add [`.nyc_output`](https://github.com/bcoe/nyc/issues/197) to `.gitignore` 330 | 331 | ## Limit Built Branches on Travis 332 | 333 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-limit-built-branches-on-travis) 334 | - add `branches` to `travis.yml` 335 | ```yml 336 | branches 337 | - only 338 | - master 339 | ``` 340 | - `only` for whitelisting and `exclude` for blacklisting 341 | - `branch-name` (`master`) could also be a `regex` 342 | - travis will continue to build for pull requests 343 | 344 | ## Add a browser build to an npm module 345 | 346 | [Direct link to the video tutorial](https://egghead.io/lessons/javascript-add-a-browser-build-to-an-npm-module) 347 | - `$ npm i -D webpack` 348 | - create `webpack.config.babel.js` 349 | - for example, checkout [getting-started/#config-file](http://webpack.github.io/docs/tutorials/getting-started/#config-file) 350 | - add `libraryTarget: 'umd'` to `output` 351 | - add `library: ` to `output` 352 | - add `devtool: 'source-map'` to main config 353 | - install [`loaders`](https://webpack.github.io/docs/using-loaders.html) 354 | - `$ npm i -D babel-loader` 355 | - rename the current `package.json/script.build` to `package.json/script.build:main` 356 | - add `"build:umd": "webpack --output-filename .umd.js"` to `package.json/script` 357 | - add `"build:umd:min": "webpack --output-filename .umd.min.js" -p` to `package.json/script` 358 | - `-p` for production build, minify the code 359 | - `"build": "build:main && build:umd && build:umd:min"` to `package.json/script` 360 | - alternatively 361 | - `$ npm i -D npm-run-all` 362 | - `"build": "npm-run-all build:*"` to `package.json/script` 363 | - update `readme` to point to `https://unpkg.com/@/path/to/umd/file` 364 | --------------------------------------------------------------------------------