A horrible introduction to using modern JavaScript tooling with D3
Chapter 9
It’s pretty cool how with just one command - eslint --fix
- we were able to solve so many problems with our code! And I mean, not even problems, but it just made things look nicer.
But maybe nice isn’t enough. Maybe nice is fine, but we want something more. We want our code to be… prettier?
eslint
has a pretty good number of opions about things, but sometimes it just isn’t enough. We want some evil editor, some highly demanding lead programmer, some paragon of artistic virtue who will smash our fingers with a hammer if we don’t hit enter and tab in all the right places.
That, my friends, is Prettier. According to the Prettier website:
Prettier is an opinionated code formatter. It enforces a consistent style by parsing your code and re-printing it with its own rules that take the maximum line length into account, wrapping code when necessary.
Prettier can work with eslint to really really standardize your code into something that is super-readable and easy for your coworkers/teaching assistants/instructors/students/friends/neighbors/enemies/etc to read and understand.
So what’s the difference between Prettier and eslint?
eslint is mostly about code quality, like no unused variables. The fact that it checks our quotation marks and stuff is just extra fluff. Prettier is mostly about code formatting, so it loves to criticize quotation marks and semicolons and lines being too long and stuff.
Let’s install Prettier using npm
! We’ll also install a few plugins that allow it to work with eslint
.
Just like we got an eslint
command when we installed eslint
, we now have a prettier
command since we installed prettier
. We don’t want to do the whole ./node_modules/.bin/prettier
thing, though, so let’s just add a new script to package.json
. We’ll called it prettier
.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint --fix graph.js",
"prettier": "prettier graph.js"
},
If we run npm run prettier
, it spits the fixed-up file back at us. I dunno, that doesn’t seem useful, I’d rather have it do something like --fix
did for eslint
, and automatically save the cool new version.
Let’s add the --write
option…
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint --fix graph.js",
"prettier": "prettier --write graph.js"
},
…and run npm run prettier
again.
It worked! It changed a bunch of stuff about our file! Look at that cool new formatting!
/* global d3 */
var datapoints = [
{ name: "New York", population: 8 },
{ name: "Los Angeles", population: 3.9 },
{ name: "Washington, DC", population: 0.7 }
];
var svg = d3
.select("body")
.append("svg")
.attr("height", 100)
.attr("width", 400);
var xPositionScale = d3
.scaleLinear()
.domain([0, 8])
.range([0, 200]);
svg.selectAll("circle")
.data(datapoints)
.enter()
.append("circle")
.attr("r", 10)
.attr("cx", function(d) {
return xPositionScale(d.population);
})
.attr("cy", function(d, i) {
return 100 * i;
});
Amazing! Great! Now let’s run eslint
on it again, just to make sure.
And our file changes again…
/* global d3 */
var datapoints = [
{ name: 'New York', population: 8 },
{ name: 'Los Angeles', population: 3.9 },
{ name: 'Washington, DC', population: 0.7 }
]
var svg = d3
.select('body')
.append('svg')
.attr('height', 100)
.attr('width', 400)
var xPositionScale = d3
.scaleLinear()
.domain([0, 8])
.range([0, 200])
svg.selectAll('circle')
.data(datapoints)
.enter()
.append('circle')
.attr('r', 10)
.attr('cx', function (d) {
return xPositionScale(d.population)
})
.attr('cy', function (d, i) {
return 100 * i
})
…wait a second. Waaaaait a second. Try running npm run prettier
one more time, and see what happens.
Oof. It looks like they can’t agree. Our “Standard” eslint
style guide uses single quotes and no semicolons, but Prettier just changes it all back. Who should we trust?! Who is the True King?!
Well, I am, and I say: no semicolons, single quotes, but also I really want to use Prettier. In order to do this, we’re going to set up Prettier to run as part of eslint, and give it a few changes to its default rules.
In order to do this, we need to open up the secret .estlintrc
file hiding in the same folder. It currently looks like this:
We’re going to make a few tiiiiny tiny adjustments to make the two be friends:
{
"extends": ["standard", "prettier", "prettier/standard"],
"plugins": [
"prettier"
],
"rules": {
"prettier/prettier": [
"error",
{
"singleQuote": true,
"semi": false,
"printWidth": 80
}
]
}
}
This plugs the prettier
into eslint
. Try pasting a somewhat edited version of our old graph.js
code in there:
/* global d3 */
var datapoints = [ { name: "New York", population: 8 },
{ name: "Los Angeles", population: 3.9 },
{ name: "Washington, DC", population: 0.7 }
]
var xPositionScale = d3.scaleLinear().domain([0, 8]).range([0, 200])
var svg = d3.select("body").append("svg").attr("height", 100).attr("width", 400)
svg.selectAll('circle').data(datapoints)
.enter().append('circle')
.attr('r', 10)
.attr('cx', function (d) {
return xPositionScale(d.population);
})
.attr('cy', function (d, i) {
return 100 * i;
})
And now run the linter
Quotation marks are fixed, semicolons removed, indenting solved, long lines shortened, etc etc etc. It’s fixed, it’s nice, it’s prettier!
This is great and all, but… maybe even though it does all this work, I’m still a little too lazy to do all that?