Kent C. Dodds

Utah

wife, 4 kids, & a dog

PayPal, Inc.

Tools of modern JavaScript Projects

Please Stand...

if you are able ❤️ ♿️

What this talk is

  • Opinionated
  • Experienced

What this talk is not

  • Covering everything you need for every application
  • Perfect for every scenario

Let's
Get
STARTED!

What makes a

tool "good" ?

  1. Does the job you need
  2. Wide "pit of success"

What is a

"pit of success" ?

What makes a "pit of success" wide?

  1. Simple
  2. Automatic

Before we get to tools...

How do we get them?

  1. Ubiquitous
  2. Fast
  3. Reliable
  4. De-facto

Let's start with the user interface

  • Fast and easy to build and maintain
  • Great community of educational material, support, and libraries
  • Transferrable skills (small domain-specific API)
  • "Easy to reason about..." 🙃

Handy Libraries

axios

react-intl

How about code optimization?

  • Use the latest features of JavaScript without worrying about browser support.
  • Precompile code at build time.
  • Easily integrate with other tools we want to use

Great babel plugins/presets

babel-preset-env

babel-plugin-lodash

babel-plugin-transform-react-remove-prop-types

babel-plugin-module-resolver

babel-plugin-transform-react-constant-elements

babel-plugin-react-intl

babel-plugin-preval

babel-plugin-console

See awesome-babel for more

babel-plugin-codegen

What about the build pipeline?

  • Load only the things we need when they're needed
  • Allows us to structure things in a way that's easy to maintain
  • Easily integrate with other tools we want to use

Related Tools

react-loadable

webpack-config-utils

html-webpack-plugin

offline-plugin

See awesome-webpack for more

How about code quality?

  • Reduces the number of tests we need to write
  • Increases our confidence when refactoring
  • Brings static types to JavaScript
  • Can quickly add it to an existing codebase and get value
  • Easily integrate with other tools we want to use

What about discouraging suboptimal patterns?

  • Reduces the number of tests we need to write
  • Increases our confidence when refactoring
  • Totally pluggable, allowing us to do custom pattern checks
  • Easily integrate with other tools we want to use

ESLint

ESLint

Helpful configs & plugins

eslint-plugin-jest

eslint-plugin-jsx-a11y

eslint-plugin-security

eslint-plugin-react

eslint-plugin-babel

eslint-plugin-import

And tools to improve development workflow?

  • Eliminates need to argue over code format.
  • Formats code for you automatically as you go.
  • Integrates well with all major editors.

Supporting Tools

lint-staged 🚫💩

husky 🐶

lint-staged 🚫💩

husky 🐶

What about debugging?

  • Great debugging experience, even in production
  • Allows for extensibility
  • Ubiquitous

Handy extensions and tips

react devtools

redux devtools

a11y devtools

node --inspect

react devtools

node --inspect

How do we test our JavaScript?

  • Straightforward and minimal setup required
  • Integrates seamlessly with existing tools
  • Easy to write unit and integration tests (especially async)
  • Quick feedback on broken tests that is easy to triage
  • Extremely fast even for large codebases

Helpful Jest Companion

react-testing-library 🐐

Ok, but what about End-to-End?

  • NOT FLAKEY
  • Test debuggability
  • Mocking/Proxying capabilities
  • Quick feedback on broken tests that is easy to triage

debbugging

import generateArticleData from '../../other/generate/article'
import {visitApp, sel, loginAsNewUser} from '../utils'

describe('Posts', () => {
  let cleanupUser
  before(() => {
    return loginAsNewUser().then(({cleanup}) => {
      cleanupUser = cleanup
    })
  })

  after(() => {
    return cleanupUser()
  })

  it('should allow you to create new posts', () => {
    const {title, description, body, tagList} = generateArticleData()
    const shortBody = body.slice(0, 10)
    visitApp('/editor')

    // create the post
    fillInPostDetails({title, description, body: shortBody, tagList})
    cy.get(sel('submit')).click()

    // validate the post
    validatePostDetails({title, body: shortBody, tagList})

    // edit the post
    cy.get(sel('edit')).click()
    const newDetails = {
      title: `${title}_`,
      description: `${description}_`,
      body: `${shortBody}_`,
      // TODO handle changing tags
    }
    fillInPostDetails(newDetails)
    cy.get(sel('submit')).click()

    validatePostDetails(Object.assign({}, newDetails, {tagList}))
  })
})

function fillInPostDetails({title, description, body, tagList = []}) {
  cy.get(sel('title')).clear().type(title)
  cy.get(sel('description')).clear().type(description)
  cy.get(sel('body')).clear().type(body)

  tagList.forEach(tag => {
    cy.get(sel('tags')).type(tag).type('{enter}')
  })
}

function validatePostDetails({title, body, tagList = []}) {
  cy.get(sel('title')).should('contain.text', title)
  cy.get(sel('body')).should('contain.text', `${body}\n`)
  tagList.forEach((tag, index) => {
    cy
      .get(`${sel('tags')} li:nth-child(${index + 1})`)
      .should('contain.text', tag)
  })
}

Shoutout to some other random tools

nps

create-react-app

GitHub

babel-codemod

now.sh

netlify

cross-env

npx

Next.js

Gatsby

nps

npx

create-react-app

babel-codemod

now.sh

And That's All 😀

... we have time for

Thank you!

Tools of modern JavaScript projects

By Kent C. Dodds

Tools of modern JavaScript projects

The cry of JavaScript fatigue still echoes in the minds of developers everywhere as they try to wade through the waters of outdated blog posts, tutorials, Stack Overflow answers, and GitHub repos. Just when things seem to start settling in JavaScript, something new comes to shake things up a little bit. I’ll be you tour guide as we navigate through the tooling set up of a modern JavaScript project that’s leveraging these tools in a way that actually enhances the experience of users using the project and developers working on it.

  • 7,405