Aukland Node.JS Meetup

More Betterer

Bringing order to a chaotic codebase

Who is this guy?

Senior Engineer @ Lightbox

New Job

Day 1

And then

You see the code

Remember, it could be worse.

It could be .Net

Let's starting exploring

First Stop

package.json

Scripts

{
"scripts": {
"dev": "node-dev ./bin/dev",
"build": "babel src --out-dir dist",
"pretest": "export NODE_ENV=test && node src/utils/db-setup.js",
"test": "mocha \"src/**/*-spec.js\" --require=env-test --compilers js:babel-register --recursive",
"posttest": "export NODE_ENV=development",
"model:create": "node bin/model.js ",
"migrate:create": "node bin/migration.js ",
"migrate:run": "knex migrate:latest",
"seed:run": "knex seed:run",
"seed:make": "knex seed:make",
"fixtures": "node src/utils/fixtures.js",
"precov": "export NODE_ENV=test",
"cov": "nyc npm test",
"fe:build": "webpack",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
"plato": "es6-plato -r -d report src",
"lint": "eslint ./src"
}
}

Use ⬆️ and ⬇️ keys

Dependencies

{
"dependencies": {
"bcrypt": "^3.0.2",
"bluebird": "^3.4.6",
"body-parser": "^1.15.2",
"bookshelf": "^0.10.2",
"bookshelf-camelcase": "^1.1.4",
"bulma": "^0.2.1",
"chalk": "^2.4.1",
"cookie-parser": "^1.4.3",
"ejs": "^2.5.2",
"es6-plato": "^1.0.18",
"exlist": "^0.7.0",
"express": "^4.14.0",
"express-conditional-middleware": "^1.1.2",
"express-ejs-layouts": "^2.2.0",
"express-graphql": "^0.5.4",
"express-list-endpoints": "^4.0.0",
"express-session": "^1.14.1",
"flash": "^1.1.0",
"graphql": "^0.7.2",
"graphql-bookshelf": "0.0.8",
"jsonwebtoken": "^7.1.9",
"knex": "^0.12.5",
"mysql": "^2.11.1",
"passport": "^0.3.2",
"passport-jwt": "^2.1.0",
"react": "^15.4.0",
"react-dom": "^15.4.0",
"requiredir": "^1.0.7",
"serve-favicon": "^2.3.0",
"sqlite3": "^3.1.6",
"to-case": "^2.0.0",
"xtconf": "^2.0.0"
}
}

Use ⬆️ and ⬇️ keys

What else?

  • engines (What versions of node and npm it supports)
  • Jest
  • Babel
  • Browserify
  • ???

Configuration

Look for process.env. or JSON files

Database

Migrations?

Routes

Routes Testing

require('approvals').mocha();
const assert = require('assert');
const listEndpoints = require('express-list-endpoints');
const app = require('./app.js')
describe('The routes', () => {
it('should have the same routes', () => {
const routes = listEndpoints(app);
this.verifyAsJSON(routes, {
reporters: ['copycommand']
});
assert.ok(true);
});
});

Use ⬆️ and ⬇️ keys

Tests

Establish baselines

Routes Testing

const request = require('supertest')
const assert = require('assert')
const faker = require('faker')
const app = require('../../server')
const User = require('../../models/user')
describe('The Home Controller', () => {
it('should register a new user', done => {
const email = faker.internet.email()
const firstName = faker.name.firstName()
const lastName = faker.name.lastName()
request(app)
.post('/register')
.send({ email, firstName, lastName, password: 'password' })
.expect(304)
.end((err, res) => {
assert.ok(res.header.location === '/login')
done()
})
})
it('should allow a user to login', done => {
const email = faker.internet.email()
const firstName = faker.name.firstName()
const lastName = faker.name.lastName()
const password = 'password'
User.register(firstName, lastName, email, password)
.then(() => {
request(app)
.post('/login')
.send({ email, password: 'password' })
.expect(304)
.end((err2, res2) => {
assert.ok(
res2.header.location.indexOf('/') > -1,
'The location is wrong'
)
done()
})
})
.catch(() => {
assert(false)
})
})
it('should not allow a user to login with wrong password', done => {
const email = faker.internet.email()
const firstName = faker.name.firstName()
const lastName = faker.name.lastName()
const password = 'password'
User.register(firstName, lastName, email, password)
.then(() => {
request(app)
.post('/login')
.send({ email, password: 'passwordx' })
.expect(304)
.end((err2, res2) => {
assert.ok(res2.header.location === '/login')
done()
})
})
.catch(() => {
assert(false)
})
})
})

Use ⬆️ and ⬇️ keys

Quality Analysis

Route response times

Monitoring

  • Response times
  • Resources
  • "Golden" Routes

Incremental Change

The mess didn't happen overnight, you can't be expected to solve it immediately