D3 + JavaScript Tooling's Not (Just) For Unicorns

A horrible introduction to using modern JavaScript tooling with D3

Chapter 15

External files and Parcel

When we’re working on D3, we very quickly get to where we’ll be using external files for our data. For example, let’s start with a new index.html and graph.js.

index.html

graph.js

countries.csv

country,continent,gdp_per_capita,life_expectancy,population
Afghanistan,Asia,663,54.863,22856302
Albania,Europe,4195,74.2,3071856
Algeria,Africa,5098,68.96300000000001,30533827
Angola,Africa,2446,45.233999999999995,13926373
Antigua and Barbuda,N. America,12738,73.544,77656
Argentina,S. America,10571,73.822,36930709
Armenia,Europe,2114,71.494,3076098
Australia,Oceania,29241,79.93,19164351
Austria,Europe,32008,78.33,8004712
Azerbaijan,Europe,2533,66.851,8110723
Bahamas,N. America,22728,72.37,297651
Bahrain,Asia,22015,74.497,638193

Try running python -m http.server and visit localhost:8000 - everything will work perfect!

Now try running parcel index.html and visit localhost:1234 - everything will be broken!

If we open up the console, our error seems to be…

GET http://localhost:1234/countries.csv 404 (Not Found)

…which is weird, because we definitely saved countries.csv. Go look! It’s there!

Big secret: Parcel is serving our content out of another secret folder. After it processes our index.html and graph.js, it sends them over to dist/, where it is running the actual server. If you open up the folder, you’ll see: no countries.csv!

We have two solutions:

  1. The VERY BAD solution: copy countries.csv into dist
  2. The PERFECT solution: change our code to work with Parcel

The very bad solution seems good because it keep our code as normal JavaScript, and allows our code to keep working with python -m http.server. But… I’m sorry, we’re in too deep, we have to stop writing “real” JavaScript and start writing what Parcel wants.

Instead of writing

We need to use require to tell Parcel that countries.csv is an external, required file, and it needs to include it in dist/. The change looks like this:

The ./ part means “inside of this same directory.” Give it a save, the page will auto-refresh, and voilà! It works.

You’re going to forget this all the time. And even when you remember the require part, you’re going to forget the ./ part. I am so sorry, but it’s just how it has to be.