A little fun with Javascript

Just playing around with the spread operator and I found a neat little design pattern I think I am going to work in:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
let testArr = [9,1, 2, 6, 3, 4];
const newMax = (arr) => {
  if(arr.length === 1) { return console.log('end')};
  var [a, ...arr] = arr;
  let max = Math.max(a,...arr);
  console.log(max ,' >=', ...arr);
  newMax(arr);
}
newMax(testArr);
//output
9 ' >=' 1 2 6 3 4
6 ' >=' 2 6 3 4
6 ' >=' 6 3 4
6 ' >=' 3 4
4 ' >=' 4
end

Seems a fun way to look for edges like in the water trap toy problem? I am not sure, but it will be fun to play around with it.

Another thing that used to annoy me was how you had to use string concatenation. It just looked so ugly. I finally (okay I am late to the party) started using backticks for multi-line parties!

1
2
3
4
5
6
7
8
var motion = `Le mouvement de lacet sur la berge des chutes du fleuve,
Le gouffre à l’étambot,
La célérité de la rampe,
L’énorme passade du courant
Mènent par les lumières inouïes
Et la nouveauté chimique
Le voyageurs entourés des trombes du val
Et du strom.`

And finally a little more fun with the spread operator (thanks Alex Rauschmayer) but you can make an array only contain unique values in a very clean, native way.

1
2
3
4
const arr = [7, 3, 1, 3, 3, 7];
[...new Set(arr)]
//returns
[ 7, 3, 1 ]

Front Ends… who needs em!

I have always preferred to work on the back end. It seems more peaceful there. The front end is all colors, moving stuff, and clicks!! Why should I care about clicks… I respond to requests no clickity click click demands! I am fine seeing JSON shoved on the screen, I will parse it visually, personally. I don’t need fancy filters, sorters and interfaces for data.

This opinion puts me most certainly in the minority, so as every good developer does, I forced myself to do something that made me uncomfortable, make a front end. A little background, the project is a way for me to organize my interviews. I needed a place to hold the questions, let me run through them, add notes, and rate the candidate etc.

The api was written with hapijs, my new personal favorite node framework. I was waffling about what to choose for the client side of things. I have already built a few things with Angular 1.5 so I was contemplating Angular 2, but that would go against the reason I am doing this in the first place. I mean if I am going to go out of my comfort zone, it might as well be way out. I could do it in pure vanilla js, but again I am quite familiar with that.. Come on John! Think… think… A-ha! React. I hear about it constantly. It seems to solve some issues with rendering speeds. It has cool terms like ShadowDOM and JSX that remind me of hackers and superbikes in a cyberpunk movie.

ShadowDOM leapt, turning mid-air. Using a neural link to control JSX superbike, it started just before her ass slammed into the seat and exploded violently forward…”

I am a few days in now. I have the basic CRUD working, and you know what? I don’t hate it! I like the way react apps come together. Nice and modular, with plenty of opportunity to build reusable components, really fun stuff. So I guess the lesson learned is to keep yourself confused and uncomfortable. Sounds like fun!

 

100% Code Coverage or Die!

I have been working on my next tutorial. It will be a hapi.js api (maybe even with a React/Redux client) as close to production quality as I can get without a different (aka better) hardware infrastructure. Quality error messages, logging, input validation, fully documented, authentication with scopes and most importantly testing with 100% code coverage.

This is what I am currently working on and it’s been interesting learning how Hapi.js gets tested and what differences configuration over coding makes in my approach. So far I like it even though I am struggling with some specific routes. It is always fun to learn something new and feel that struggle again. I certainly prefer to have to work at something for a bit over working on the same thing over and over again.

I should have something ready in the next few days, maybe a week! I swear I just love coding so much!

 

Publishing an NPM Module Part 7

These are my notes based on the phenomenal tutorial by Kent C. Dodds hosted by egghead.io both of which are my go to sources when I want to learn something new. I highly suggest you sign up for the pro subscription.

Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | >Part 7

Part 7: Making a Browser Build

Now what if we wanted to make it so a website could consume our nifty library? We could force them to create a node api to use our wonderful features. Or we could be nice and just let them load up via cdn! I think we should go that route. So first we need to install webpack the module bundler! In a nutshell webpack will take all of your various bits and bobs and package them up. So head to your project folder in your console and type:

$ npm i -D webpack

Now we need to create a basic config file for it.

import {join} from 'path'

const include = join(__dirname, 'src');

export default {
    entry:  './src/index',
    output: {
        path: join(__dirname, 'dist'),
        libraryTarget: 'umd',
        library: 'randomCharacterName',
    },
    devtool: 'source-map',
    module: {
        loaders: [
            {test: /\.js$/, loader: 'babel', include},
            {test: /\.json$/, 'loader': 'json', include}
        ]
    }
}

Entry is pretty simple, where do we look for the app? Output is also fairly self-explanatory, where do we put the distributed files and what do we do with them. Path is the place, libraryTarget is what format we will be exporting, in our case we are using umd and finally library is just the name of the library. The devtool section specifies a tool to help with debugging in our case we are using source-map to help us track down where errors are actually occurring.  The modules section allows us to use certain loaders. In our case we will be using babel load and json loader.  In fact we should probably install them!

$ npm i -D babel-loader json-loader

Now that those are in place we need to modify a few things in our package.json file. We are going to rename build to build:main, add build:umd and build:umd.min.

glyphicons-424-git-create
"build:main": "babel --copy-files --out-dir dist --ignore *.test.js src",
"build:umd": "webpack --output-filename index.umd.js",
"build:umd.min": "webpack --output-filename index.umd.min.js -p",

Go ahead and run:

$ npm run build:umd

Neat! Only problem now is how to we run all of these when we need to build again… There is a nifty package just for that called npm-run-all.

$ npm i -D npm-run-all

Now jump back to package.json and add in the new supercharged build script:

"build": "npm-run-all --parallel build:*",

Now after you have this all committed and pushed take a look at npmcdn.com/name-of-your-library. See mine for an example. You can go to a specific version by adding an @ to the end of the url and specifying the semver i.e. 1.6.0. You can also specify which one you want by adding a pointer to a specific file in your dist directory. 

https://npmcdn.com/random-character-name@1.6.0/dist/index.umd.min.js

All cool stuff! This is the conclusion of this tutorial. My next one will be building out an API, stay tuned.

glyphicons-55-clock  = Time Saving Idea

glyphicons-499-sunglasses = Pro Tip

glyphicons-31-pencil = Note

glyphicons-197-exclamation-sign = Alert

glyphicons-424-git-create = Code Update

glyphicons-28-search  = A Closer Look

Publishing an NPM Module Part 6

These are my notes based on the phenomenal tutorial by Kent C. Dodds hosted by egghead.io both of which are my go to sources when I want to learn something new. I highly suggest you sign up for the pro subscription.

Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | >Part 6 | Part 7

Part 6: Adding ES6 Support

We need to add babel-cli to our dev dependencies:

$ npm i -D babel-cli
glyphicons-28-search  The Docs 
Common uses:
babel -w -o  //watch for file changes and output
babel src -o  // compile entire src dir and concat
babel src -d lib //compile entire src dir and output to lib
babel --ignore  //add this to ignore files i.e. tests

Next we will add a build script for babel. Looking in our node_modules/bin we can see babel has been added making it available to npm for scripts. Let’s edit our package.json to include:

"build": "babel --out-dir dist src”

Now let’s test it to see what gets generated when we run our script. In your terminal run:

$ npm run build

Look in the dist directory and you will see that it was created and files were moved over. It also added our test files! This is something we don’t want to push to the dist since if we test when we publish, not when we consume. We can solve this by adding an ignore flag:

“build”: ''babel --out-dir dist --ignore *.test.js src"

Since this creates a dist directory with files in it, we want to make sure that if we make a change in a filename that the old one is not present in the next build in order to delete the directory cleanly we will add a prebuild script to package.json

"prebuild": "rm -rf dist”

However this is only *nix supported in order to allow windows devs to use this we must add a new dev package called rimraf  a cross-platform rm -rf built for node.

$ npm i -D rimraf

replace rm-rf with rimraf:

"prebuild": "rimraf dist”

now convert to es6 i.e.:

glyphicons-424-git-create
 
'use strict'
//require external dependencies
import uniqueRandomArray from 'unique-random-array';
import _ from 'lodash';

//define available data
import firstNames from '../data/first-names.json';
import middleNames from '../data/middle-names.json';
import lastNames from '../data/last-names.json';

//random generators
let randomFirstName = uniqueRandomArray(firstNames);
let randomMiddleName = uniqueRandomArray(middleNames);
let randomLastName = uniqueRandomArray(lastNames);

//filter functions
const filteredNames = function (nameList, initial) {
 return nameList.filter(function (name) {
 return name[0] === initial;
 })
};

//methods
const list = ()=>{
 let allNames = ["FirstName MiddleName LastName"];
 for (var i = 0; i < firstNames.length; i++) {
 //Math.floor((Math.random() * 10) + 1);
 var tmpName = randomFirstName() + ' ' + randomMiddleName() + ' ' + randomLastName();
 allNames.push(tmpName);
 }
 return allNames;
};


const single = ()=>{
 return randomFirstName() + ' ' + randomMiddleName() + ' ' + randomLastName();
};

const startsWithLetter = (f, m, l)=>{
 var firstName = _.sample(filteredNames(firstNames, f));
 var middleName = _.sample(filteredNames(middleNames, m));
 var lastName = _.sample(filteredNames(lastNames, l));
 return firstName + ' ' + middleName + ' ' + lastName;
}

const numberOfNames = (number=1, allNames=[])=>{
 for (var i = 0; i < number; i++) {
 var tmpName = randomFirstName() + ' ' + randomMiddleName() + ' ' + randomLastName();
 allNames.push(tmpName);
 }
 return allNames;
}

//available methods
module.exports = {
 list: list,
 single: single,
 startsWithLetter: startsWithLetter,
 numberOfNames: numberOfNames
}

Now lets run our build script again:

$ npm run build

Now let’s take a look at index.js in dist and notice nothing happened! That is because really all we did was have it copy it over. We did not tell it to do anything! So we need to install some presets to tell babel how to do the transpiling:

npm i -D babel-preset-es2015 babel-preset-stage-2
glyphicons-28-search Learn more about presets

In order for babel to know about these presets we have added we need to change our package.json to reflect this:

"babel": {
  "presets": [
    "es2015",
    "stage-2"
  ]
}

 

 

We need to change our package.json file to point to dist now:

"main": "dist/index.js",

While we are here we should update the build script by adding –copy-files:

"build:main": "babel --copy-files --out-dir dist --ignore *.test.js src",

 

Now we need to make sure the build script runs before the publish script. We do this by modifying the .travis.yml file scripts section, after check-coverage add:

- npm run build

Now we need to do a little verification on our changes. Let’s run a command to see what will actually be published:

$ npm pack   

A file was generated ending in tgz. Open that up and take a peek. It looks alright, but there are just some extra files in there that we might not need or want. So let’s learn how to limit what gets packed up. We do this by adding a files section to our package.json file:

"files": [
  "dist",
  "data",
  "README.md"
],

  Now that we are writing in ES6 we want to make sure that all of the other pieces are able to work with the new syntax as well. Let’s start with istanbul. It turns out we need a replacement package for that called nyc.

$ npm i -D nyc

Now we need to update package.json to use this new method:

glyphicons-424-git-create
"check-coverage": "nyc check-coverage --statements 100 --branches 100 --functions 100 --lines 100",

Next in the test with the watch command (-w) we want to add in something that will transpile our code. 

"test:watch": "mocha src/index.test.js --compilers js:babel-register -w",

Since we are using it we might as well install it!

npm i -D babel-register

The tests are getting a little clunky, with a lot of repeated code so we are going to clean things up a bit. by letting the watch test just fire off the regular test adding in a -w flag.

"test:watch": "npm t -- -w",
"test": "mocha src/index.test.js --compilers js:babel-register",

Note the double dash in the watch script. This allows you to send in the watch flag to the previous call as if it were in the original.  Since we are cleaning things up let’s go a little farther, but adding a cover script.

"cover": "nyc --reporter=lcov npm t",

We now need to adjust our githook. 

"config": {
  "ghooks": {
    "pre-commit": "npm run cover && npm run check-coverage"
  }

One more spot in .travis.yml we need to make sure we run our cover script so it ends up looking like:

script:
  - npm run cover
  - npm run check-coverage
  - npm run build

 

There we go! We now have an es6 friendly set up!

Next… UMD Build!

glyphicons-55-clock  = Time Saving Idea

glyphicons-499-sunglasses = Pro Tip

glyphicons-31-pencil = Note

glyphicons-197-exclamation-sign = Alert

glyphicons-424-git-create = Code Update

glyphicons-28-search  = A Closer Look

Publishing an NPM Module Part 5

These are my notes based on the phenomenal tutorial by Kent C. Dodds hosted by egghead.io both of which are my go to sources when I want to learn something new. I highly suggest you sign up for the pro subscription.

Part 1 | Part 2 | Part 3 | Part 4 | >Part 5 | Part 6 | Part 7

Part 5: Automating Testing and Code Coverage

Automatically running tests before commits with ghooks

I really think git hooks are pretty sweet! So git has events right? commit, push, receive etc. Well what if you wanted to do stuff before you committed or after a push? Well ghooks is how you do that. 

glyphicons-28-search read more at  git-scm.com , http://githooks.com/ or on npm

Let’s get started by installing it as a dev dependency for this project. You don’t want to install it globally btw as it can cause problems.  Head to your console and type:

$ npm i -D ghooks

Now we need to configure ghooks to run our test before every commit. This is pretty easy. Go to package.json and add:

glyphicons-424-git-create
"config": {
        "ghooks": {
                "pre-commit": "npm run test:single"
        }
}

Now head into your test file and break the test by making it fail, then run:

$ git commit -am "Testing ghooks"

It should have prevented the commit, so go back and fix the test. Then let’s see it work on when we run our commit script.

$ git status
$ git diff
$ git add .
$ git status
$ npm run commit

Great! Now that we have automated the testing process a bit how about taking a look at how much of our code is covered by our tests? How would we do this? There are several ways but I am most comfortable with Istanbul, it has great docs and is pretty widely used.

Adding code coverage with Istanbul

Install  istanbul as a dev dependency:

$ npm i -D istanbul

Verify in package.json that istanbul was added to the devDependencies section. Now we need to adjust the test scripts. Change test:single to:

glyphicons-424-git-create
“test:single”: “istanbul cover -x *.test.js _mocha -- -R spec src/index.test.js”

What is happening there? Well first we are firing off the istanbul binary and passing in cover. This passes in the cover command and saves coverage.json and reports after execution. Next we see -x to ignore checking the coverage ON our test files since we are not writing tests for tests. The _mocha tells istanbul that the next flags passed in should go to mocha and not to istanbul. Now run our test and see the difference now:

$ npm run test:single

Pretty neat eh! Let’s make it even cooler.

Adding Code Coverage Checking

open package.json and set new ghooks to:

glyphicons-424-git-create
"config": {
    "ghooks": {
      "pre-commit": "npm run cover && npm run check-coverage"
    }

Go back up to scripts in package.json and add:

“check-coverage”: “istanbul check-coverage --statements 100 --branches 100 --functions 100 --lines 100”

The –name value above set’s what percentage we want our code to pass before we let it go forward. Since this is a small project 100 is a good bet. To see what this does run:

$ npm run check-coverage

Now add a new function to your index.js and run tests again. I simply created  a dummy function:

function notCovered() {
     return 'oops';
}
$ npm run test: single

This will let us check the coverage of that specific test allowing us to re-run check-coverage:

$ npm run check-coverage

Now since we are all about the automation we want to add this to Travis so open .travis.yml and add to script: section

glyphicons-424-git-create 
- npm run check-coverage

Sweet! Now remove that bunk function before we forget. Now we are going to add codecove.io report viewing to the project. I mean why not right?

Go to codecov.io and sign up for an account. Integrate your repo for the npm module. The steps are pretty straight forward. Now go to the terminal and from within the project directory run:

$ npm i -D codecov.io

Then go to package.json we will pipe a report into the codecov binary by adding a new script to package.json:

“report-coverage”: “cat ./coverage/lcov.info | codecov”

Now on to .travis.yml (this pattern is getting familiar right?)

after_success:

- npm run test report-coverage

 

$ git status
$ git add .
$ npm run commit
$ git push

Check code coverage at codecov.io. Optionally you can add a chrome extension for codecov here to see more integration on github.com.

Now wasn’t that easy!

Adding badges to the Readme

Head to http://shields.io and search for Travis copy url into README.md then edit the url to be your repo. You can also look at the styles at the bottom if you want to tweak the shield. Do the same for:

  • codecov
  • npm version
  • npm downloads
  • npm license
$ git status
$ git add .
$ npm run commit
$ git push

Next… ES6 support!

Key:

glyphicons-55-clock  = Time Saving Idea

glyphicons-499-sunglasses = Pro Tip

glyphicons-31-pencil = Note

glyphicons-197-exclamation-sign = Alert

glyphicons-424-git-create = Code Update

glyphicons-28-search  = A Closer Look

Publishing an NPM Module Part 4

These are my notes based on the phenomenal tutorial by Kent C. Dodds hosted by egghead.io both of which are my go to sources when I want to learn something new. I highly suggest you sign up for the pro subscription.

Part 1 | Part 2 | Part 3 | >Part 4 | Part 5 | Part 6 | Part 7

Part 4: Automating Releases

As developers we should be looking to automate as much as we can. Setting SemVer values is certainly one we should do. One reason is to reduce how much we have to remember for regular tasks, another is removing emotion from versioning. Check out this video for some other nifty reasons. It is pretty straightforward to set up.

First let’s install it globally.

$ npm install -g semantic-release-cli

Now that it is installed we can run through a nice little wizard to configure it. Making sure you are in your module folder type:

$ semantic-release-cli setup

There are several prompts:

  • Whether your GitHub repository is public or private
  • Which NPM registry you want to use (Default: https://registry.npmjs.org/)
  • Your NPM username (unless passwords were previously saved to keychain)
  • Your NPM email
  • Your NPM password
  • Your GitHub username
  • Your GitHub password (unless passwords were previously saved to keychain)
  • Which continuous integration system you want to use. (Options: Travis CI / Pro / Enterprise, or Other)
  • Whether you want to test a single node.js version (e.g. – 0.12) or multiple node.js versions (e.g. – 0.10, 0.12, etc.)

Enter your information, most of them will default to the right one, just make sure for the CI question that Travis-CI is chosen and for the node version select single node.

Let’s see what happened! Looking at package.json we see a new script semantic-release.

"semantic-release": "semantic-release pre && npm publish && semantic-release post"

Also notice that the version section of package.json has vanished. Travis-CI will handle that now, however to suppress a warning message when we release the npm package let’s add it back in as:

"version": "0.0.0-semantically-released"

It also updates the url to https and adds semantic-release to the dev dependencies. Let’s configure travis.yml a little by adding our test script in the chain, between before: and after: add:

        Script:
        - npm run test

This will make sure that our tests are run when our CI attempts to publish them.

glyphicons-28-search To learn more head over to the modules readme here.

Being a good Commitizen

Let’s install commitizen to help us keep our commit messages consistent in order to help our versioning system to be even more emotionally agnostic.

In your terminal run:

$ npm i -D commitizen

Next we need to tell it which standard to follow for our messages. I go with a fairly standard one used by the AngularJS team called… conventional changelog!

glyphicons-28-search You can read more about it here.

To install it simply type:

$ npm i -D cz-conventional-changelog

glyphicons-499-sunglasses If you are pretty settled on these then you can install them with -g instead of -D. If you do that there is a bit more setup involved. Go here for more info.

This adds bin to node-modules for us to use in our npm scripts called git-cz. You could just run the following instead of git commit:

$ git cz

glyphicons-499-sunglassesYou can use all the git commit options with git cz, for example:
git cz -a.

However we are going to set up a script in our package.json to make things a little cleaner and a bit more obvious. Simply add a new script with the following:

"commit": "git-cz"

Then we need to tell it to use our cz-conventional-changelog, in the config section (create one if you don’t have one) add:

 "config": {
    "commitizen": {
        "path": "node_modules/cz-conventional-changelog"
    }
  },

Let’s stage these changes.

$ git status
$ git add -A
$ git status

Before we run our new nifty script head over to your repo on github and create an issue. For this let’s make it something like “standardize commit messages”. This is probably your first issue, however if it is not take note of the number and use that for the final prompt.

Now that everything is staged we can run (on the last prompt put closes #1):

$ npm run commit

Automatically Releasing with Travis-CI

$ git status
$ git push

Look at the repo and notice the closed issue. Go to travis-ci.org/the-name-of-your-repo notice the problem? It is stuck at the testing phase. This is because we have a -w on our test command so it will never close. To fix this we are going to add a script to our package.json:

glyphicons-424-git-create
“test:single”: “mocha src/index.test.js”

We also need to edit .travis.yml and change our npm run call:

glyphicons-424-git-create
- npm run test:single

Go back to travis-ci.org and cancel the build.

Let’s try that again in your console:

$ git status
$ git add .
$ npm run commit

Now watch travis-ci, note the version number change. Look at github release, look at npm see how the version change has propagated across the multiple distributions.  We are cooking with gas now!

Next… Automating Testing and Code Coverage!

Key:

glyphicons-55-clock  = Time Saving Idea

glyphicons-499-sunglasses = Pro Tip

glyphicons-31-pencil = Note

glyphicons-197-exclamation-sign = Alert

glyphicons-424-git-create = Code Update

glyphicons-28-search  = A Closer Look