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" ?
- Does the job you need
- Wide "pit of success"
What is a
"pit of success" ?
What makes a "pit of success" wide?
- Simple
- Automatic
Before we get to tools...
How do we get them?
- Ubiquitous
- Fast
- Reliable
- 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.
- 8,434