One of my least favorite things about starting new JavaScript projects is setting up all the configuration needed to write modern JavaScript. I happily refused to commit Webpack configuration to memory, but the result is an unpleasant feeling whenever I'm starting a project.
If I'm writing a React app, which is most of the time, the problem is solved for the most part with the create-react-app
scaffolding tool. Leveraging react-scripts
, all of the gnarly Webpack configuration is hidden away until you eject.
But when I started my recent series on generative art, I ended up borrowing an ES6 starter project and adding a bit of boilerplate for P5.js. Copying and pasting the scaffolding of a project works fine, but when someone referred me to Parcel, I jumped at the chance to evaluate it. I’m going to take the P5.js ES6 starter I put together for the first generative art column and rewrite it using Parcel to see how it works.
Parcel bundler in action
In my eyes, the “Hello World” example on the Parcel website claims you can simply write HTML, CSS, and JavaScript using all the new and fancy ES6 features and you don't have to write any configuration at all. Just install the parcel-bundler
package and point it at your main HTML file. Any of the transforms, transpilations, packaging, and even dependency installations are taken care of for you. Truly? Let’s see.
The recommended way to get started with Parcel is by globally installing the package. This smells to me, having been through projects recommending global installs then converting to local installs with a global handler (think Grunt and Grunt CLI). There is a local install option, too, so you can always take the local route if you like. I’ll dive right into the deep end:
#yolo
yarn global add parcel-bundler
The parcel
command exposed by that global install needs to point to an HTML file, after which it can watch for changes, repackage code, and perform hot module reloading. I’m going to set up a bare-bones HTML file to start, then have Parcel running for the whole rest of the process:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>P5.js ES6 Starter</title>
</head>
<body>
</body>
</html>
Then I’ll run parcel index.html
. It looks fine so far:
Parcel has created a dist
directory and put my HTML file (as is) into it.
Note: Throughout the course of testing this, I want to test hot module reloading, which requires some minor configuration changes for some IDEs and editors. I’ve done the necessary config setting for Vim to make this work.
Okay, the next step is to add a JavaScript file and update the HTML file to directly include that JavaScript file:
// scripts/index.js
const myLog = () => {
console.log('some arrow function goodness');
};
myLog();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>P5.js ES6 Starter</title>
</head>
<body>
<script src="./scripts/index.js"></script>
</body>
</html>
When I save that, Parcel builds a JavaScript file and a map file, throws it into the dist
directory, and updates a reference to the script with a hashed key in it, but I don’t see the console output I’d expect. Once I refresh the page, though, we’re in business. I can change the message of the log statement and Parcel immediately rebundles and executes that code.
Parcel passes the test
That’s pretty nice so far, albeit very basic. It feels pretty good to get back to the super-accessible style of writing JavaScript code that makes it so inviting to newcomers. I want to push it further, though, and test the claim of automagical dependency installation. Our P5.js starter includes a dependency on P5, so I’ll just add the requisite import statement in my index.js file and see what happens. I’ll also add log statements that list the keys on the P5 object to prove it’s there:
import * as P5 from 'p5';
const myLog = () => {
console.log('some arrow function goodness');
console.log(Object.keys(P5));
};
myLog();
It takes a bit longer to refresh, but I could see Parcel downloading the dependency and rebundling, and then P5 methods show up in the console:
Wow. From a development experience standpoint, I’m already impressed. From my perspective, I ran a single command and after that I just had to write code. There is a lot more that goes into a good web application bundler, but Parcel passes the sniff test and then some.
Next week we’ll talk about some of the other types of files Parcel can handle automatically and dig into bundling the application for production. Want to take Parcel for a spin? I pushed up a version of the P5.js starter using Parcel, which you can download, play with, and compare against the Webpack version.
Questions or comments? Let’s continue the conversation on Twitter: @freethejazz.