There's a few things I always set up when working on a frontend project: ESLint, Prettier, husky and lint-staged.
ESLint
ESLint for linting frontend files: JavaScript, JSX and TypeScript (if the project uses TypeScript). There are all kinds of rules and plugins for this, but the gist of using a linter is to keep your code adhering to a project's standards/styles.
Prettier
Prettier is for formatting your code. It is opinionated and offers some configuration but it is minimal, for example single quotes vs. double quotes.
stylelint
stylelint as the package name implies, is a linter for Cascading Style Sheets (CSS).
Side Effect: Improving Code Reviews
ESLint, stylelint and Prettier enable you to remove any discussion of what they do from a code review, because the rules are already set in place. This is great because it allows you to focus on the actual code review which is the bug you're trying to fix or a feature you're implementing.
husky
Note: As of Husky version 7, the setup is completely different. Please follow the steps in the 4 to 7 migration guide.
husky is a node package that makes creating Git hooks a joy. What's a Git hook? It's a script that runs during an event in a repository. For example, before a commit. Once the husky package is installed, all that is required is a configuration to decide which Git hooks to use and what to run for that particular hook.
Here is a sample configuration.
"husky": {
"hooks": {
"pre-commit": "echo 'hi'"
}
}
When a file is being committed to the repository, the above configuration will run echo 'hi'
before the file is committed.
lint-staged
lint-staged is a node package that makes it easier to run tasks for staged files in a Git repository. If we go back to our example above that echo's hi, we can change that command to lint-staged
.
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
If we commit a file, the Git pre-commit hook will run lint-staged, but nothing will happen. We need to let lint-staged know what we want to do during the pre-commit. Let's get a configuration set up for lint-staged.
"lint-staged": {
"*.{js}": [
"prettier --write"
]
}
Now if we commit a file, the pre-commit hook will run and if any JavaScript files are being committed, the pre-commit hook, thanks to lint-staged will run prettier on the file and update the file with any formatting changes and then commit the file.
Putting it All Together
All these tools together make for a great automated workflow in regards to coding standards/style guidelines for a project.
Now let's bring it all together so you can use this in your own project.
You'll need to install all the dependencies mentioned above plus a few more. I'll explain why in a minute.
npm install -D eslint prettier eslint-config-prettier eslint-plugin-prettier husky lint-staged stylelint stylelint-config-standard
eslint-config-prettier
and eslint-plugin-prettier stylelint stylelint-config-standard
are required so that eslint is only in charge of rules that do not related to formatting as prettier handles formatting.
If you're wondering what the -D
is for, that's so they get installed as devDependencies
instead of dependencies
in the package.json. For more on that, see Specifying dependencies and devDependencies in a package.json file.
In the root of your project, create a file called .eslintrc.js
. This will house the eslint configuration that we want. We'll go with the eslint recommended rules.
/* eslint-env node */
module.exports = {
extends: ['eslint:recommended', 'prettier'],
plugins: ['prettier'],
parserOptions: {
ecmaVersion: 2018, // Put whatever version you want here
},
env: {
browser: true,
},
};
Note: /* eslint-env node */
is being used as it's a frontend project and the .eslintrc.js file is Node.js. It allows us to say, "This file is a Node.js file". Thanks to Rafi for pointing this out to me.
This is a base eslint configuration. If you were for example using React in your project, there would be additional configuration for React eslint rules.
In the root of your project, create a file called .stylelintrc.json
. This will house the stylelint configuration that we want. We'll go with the stylelint recommended rules.
{
"extends": "stylelint-config-standard"
}
This is a base stylelint configuration. Feel free to expand on these standard stylelint rules.
Next up we need to our husky and lint-staged configurations. In your package.json file add these two configuration sections.
"lint-staged": {
"*.js": [
"eslint —-fix",
"prettier --write"
],
"*.{css,scss}": [
"stylelint"
]
},
"prettier": {
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80,
"tabWidth": 4
}
If you don’t trust the robots for fixing your code, remove the —-fix
argument off of the eslint command.
The prettier configuration above is what I use, but feel free to tweak it to your liking.
All the moving parts are running now. If you end up using a boilerplate these tools might already be included. For example the Create React App toolchain comes with eslint.
Bonus: Run jest Tests
I added this as a bonus tip, because not all projects use jest.
But... if your project uses jest, you can also run tests related to files that are being committed.
"lint-staged": {
"*.js": [
"eslint —-fix",
"prettier --write",
"jest --findRelatedTests"
]
}
Learn More About Your Tools
I strongly encourage you to dig further into all the tools discussed. Knowing your tools really well is a super power.
ESLint, prettier, stylelint, husky and lint-staged are great tools for the frontend, now go make something great with this setup!
Until next time folks!
Top comments (5)
It would be awesome if this whole thing could be setup on any repo by running
It could, I just haven’t done it. 😎
I have created a package inspired by this npmjs.com/package/frontend-dev user can use it by running
here is the source to the repo github.com/Rafi993/frontend-dev
Great good Nick. This can be more streamlined by created personal user environments or Boilerplates, which ironically I have written about :-)
Streamline Workflow
Chuck ・ May 1 ・ 2 min read
Thanks Chuck!
Yeah, I can’t remember when boilerplates came out, but it’s a great feature on GitHub. We use it on react-slingshot.
coryhouse / react-slingshot
React + Redux starter kit / boilerplate with Babel, hot reloading, testing, linting and a working example app built in
A comprehensive starter kit for rapid application development using React.
Why Slingshot?
npm start
to start development in your default browser.npm run build
to do all this:Get Started
Initial Machine Setup
First time running the starter kit? Then complete the Initial Machine Setup.
Click "Use this template"
Click the green "Use this template" button at the top of this page and enter a name and description for your repo.
Run the setup…
I was contemplating making a template, but opted to go with explaining the moving parts instead. I could see it being more of a cli longer term which could detect the type of project, check if certain things were in place already, add lint specific rules based on project type etc.