CSS{In Real Life}

A Modern Front End Workflow

Part 2: Module Bundling with Parcel

Parcel logo on a purple gradient background

Parcel purports to be a “zero-config” alternative to Webpack, a popular Javascript module bundler. A module bundler takes separate, reusable JS files (or modules) and “bundles” them into a single file to be served to the browser, as well as minifying the output. This can improve website performance, as the browser doesn’t need to load a bunch of files individually. This in itself is very useful, but Parcel also takes care of other tasks for us out of the box, including:

  • Running a local server
  • Building and minifying HTML, CSS and assets
  • Transpiling Javascript
  • Live reloading
  • Code splitting

Using Parcel, we can do everything we already did in the previous tutorial (and much more!), while writing fewer scripts.

Creating a Parcel project

Let’s create a new project structure, similar to the one in the previous article:

my-awesome-project
  src
    icons
    images
    js
    scss
    index.html
  node_modules
  package.json

(This time I’m including any HTML files in the src directory, because they’ll get compiled too when we build the project.)

We’ll start by installing Parcel as a dependency, and we’ll also install node-sass while we’re at it (multiple packages can be listed to install them at the same time):

npm install parcel-bundler node-sass --save-dev

(If you’re creating a new project, don’t forget to run npm init first.)

We’ll need to change the file path of our stylesheet in index.html. We only need to tell Parcel the relative path of our source file, as the actual path for use in production will be generated by Parcel at buildtime.

<link rel="stylesheet" href="./scss/styles.scss" />

Parcel comes with all the commands we need to run and build our project. Simply running parcel plus the path to our index.html file is enough to run the project and watch for changes:

parcel src/index.html

We could also (optionally) tell Parcel which port to use, and instruct it to open our website in a new browser tab whenever we start it up. The following command instructs it to use port 3000, and using the --open flag it will open in a new tab:

parcel src/index.html -p 3000 --open

This is a lot to type every time we want to run the project, so I like to write an NPM script for this:

"scripts": {
	"start": "parcel src/index.html -p 3000 --open",
}

Now we only need to type npm start.

The second of parcel’s commands builds the website for production:

parcel build src/index.html

Again, we can write a script to execute this command too:

"scripts": {
	"start": "parcel src/index.html -p 3000 --open",
	"build": "parcel build src/index.html"
}

Parcel’s build command builds all the assets to a dist folder, but it doesn’t clean the folder out each time it’s run, so you can end up with duplicate files. I like to run a clean-up command before running a production build, so that we can be sure the only files built in the dist directory are the ones necessary to our project.

"scripts": {
	"start": "parcel src/index.html -p 3000 --open",
	"clean": "rm -rf dist/*",
	"build:parcel": "parcel build src/index.html",
	"build": "npm run clean && npm run build:parcel",
}

I’ve made a few small changes to our scripts:

  1. The “clean” script removes everything in the dist folder
  2. I’ve renamed the previous “build” script “build:parcel”.
  3. Now the build command runs the “clean” script followed by the “build:parcel” script.

Now go ahead and run npm start. Parcel should open your site in the browser at https://localhost:3000 and reload the page when you make any changes to your SCSS or HTML. We don’t need Browsersync, and we don’t need to write any additional scripts.

Adding plugins

We can add plugins (which are themselves NPM packages) to optimise images and create SVG sprites:

npm install parcel-plugin-imagemin parcel-plugin-svg-sprite

For the parcel-plugin-imagemin package to take effect, we need to add a config file. Add the following to a file called imagemin.config.js in the project root:

module.exports = {
	gifsicle: { optimizationLevel: 2, interlaced: false, colors: 10 },
	jpegtran: { progressive: true, arithmetic: false },
	pngquant: { quality: [0.25, 0.5] },
	svgo: {
		plugins: [{ removeViewBox: false }, { cleanupIDs: true }]
	},
	webp: { quality: 10 }
}

You can adjust the options for the desired level optimisation (see the plugin’s documentation). parcel-plugin-svg-sprite should just work out-of-the-box – run the project and try adding some SVG icons to the src/icons directory. You should then be able to use any of them in your HTML with the SVG <use> element:

<svg>
	<use href="icons/my-icon.svg">
</svg>

Transpiling

I like to write my JS using ES2015 syntax. Babel, a transpiler, converts modern Javascript to a syntax that can be read by older browsers – meaning you can write the latest JS code and have it work everywhere. That’s a pretty useful thing to include in a project starter.

Babel has a lot of different plugins and configuration options, and wading through them can feel a bit daunting. But there’s a handy package called preset-env that takes care of transforming all the features of ES2015 (think arrow functions, destructuring, spread operators), which suits me just fine, so let’s install that.

npm install @babel/core @babel/preset-env --save-dev

You can add other plugins if you want to configure Babel to suit your specific needs (e.g. if you’re using React, Vue or another framework).

Now we need to add a config file in the project root:

touch .babelrc

If we’re happy using the default config options then we don’t need to add much at all to our config file. The following will suffice:

{
	"presets": ["@babel/preset-env"]
}

The Babel documentation has more information on config options should you need it.

Parcel runs Babel for us automatically, so once we’ve installed it and created our config file we’re good to go – our code will be transpiled whenever we run npm run build.

Example

I’ve created a starter respository using the same process as in this article – feel free to clone or fork it and use it for your projects.

Coming up

So far in this series we’ve seen how to build a starter for very simple project using NPM scripts, and learnt how to use Parcel to handle more complex tasks with minimal configuration. In the third article we’ll add a simple Sass architecture to help us get up and running quickly with writing styles.

See other articles in this series