Simple HTML/CSS Workflow With Parcel
Tags: webdev, css, javascript, html
Published: 2018-10-16 23:01:57

---
title: Simple HTML/CSS Workflow With Parcel
published: true
description: Use Parcel to compile SCSS and HTML for rapid static site development workflow with nearly no configuration.
tags: webdev,css,js,html
canonical_url: https://antjanus.com/blog/web-development-tutorials/front-end-development/simple-html-css-workflow-with-parcel/
cover_image: https://antjanusblog-antjanus.netdna-ssl.com/wp-content/uploads/2018/10/IMG_5929-1024x683.jpg
---

Very recently, I started working on an HTML/CSS side project and I found myself in a state of panic. I haven't worked on plain HTML/CSS in a while. JavaScript has been part of my workflow for years and the output of that JavaScript was always a single page app.

In fact, I haven't worked on a static site in general in quite a while.

## My Naïve Start

But I knew that such a workflow, despite being super simple, needed a toolchain I could use to speed up my development and more importantly, ensure the final output is bug-free, correct, and cross-browser compatible.

As I wrote my first `index.html`, I thought immediately, "Ohhhh, I'm gonna need some templating". Nothing major, I just needed to include the header, footer, and a few other elements from other HTML files.

My first thought was to turn to PHP. I wrote quite a bit of PHP in my dev career and probably one of my favorite features of PHP was that it can be used as HTML on steroids with a simple `include`.

So I'd have a `header.php`:

```php
<html>
  <head>
   <title>Whatever - don't care atm</title>
   <link href="styles.css" ref="application/css" /> 
  </head>
  <body>
    <nav><ul><li>home</li></ul></nav>
```

```php

<?php
// index.php
include('./header.php');
?>

Page-specific content goes here!

<?php
include('./footer.php')
?>
```

And some `footer.php`:

```php

</body>
</html>
```

That way, if I change something about the page navigation, I don't have to go to numerous files to copy/paste that change.

Unfortunately, I don't have PHP installed but If I had to get it, I would.

Plus with PHP you get a slew of benefits:


- built-in programming language to generate lists for mocking stuff up
- more complicated `includes` if I wanted to -- for instance, converting `header.php` into a function that takes templating variables as arguments
- INSTANT "compilation" (eg. save, refresh and it works!)


The other problem I ran into was CSS. Plain CSS is fine but with SCSS, I could speed up my development and keep styles consistent throughout. Plus, I'd get to split my CSS into however many files I wanted to. That way, I'd define colors in variables, nest my selectors the way I like them and so on.


I figured I could do things the old-fashioned way (especially since I didn't know how to use native CSS vars):

```css

/*---------------------
Variables:

main color: blue
secondary color: orange 

nav grey: #444
*/


// Navigation section
.nav {
  background-color: #444;
}



// Footer section
.footer {
  
}

.footer a {
  color: blue;
}

```

You know, that could totally work but as I started to dread installing PHP, and using find/replace for updating "variables" in CSS, and then having one large CSS file for everything. And as my panic started to take over, I remembered Parcel.

## Introducing Parcel

Parcel is a JavaScript bundler, at least that's what you've heard, right? That's it's kinda like Webpack? 

Well, I'm not writing any JavaScript for this project (at least, I didn't plan to at this stage!).


Parcel is a very powerful compiling/process/whatever JavaScript tool that can automate your entire workflow and very easily. It's based on a zero-config ideology. It's not entirely zero-config but it has "sane" configs for 90% of use-cases. 

When I used it for Preact, React, and TypeScript, I didn't have to do much of anything to make it work. Pretty much any config you want to add is more relevant to the tool itself than Parcel.

For instance, parcel automatically exposes your compiled results on `localhost:1234`, it watches your files without being asked, and it'll alias Preact correctly to Babel for JSX compilation.

So I set off to figure out how to use Parcel for my use case and I promises myself to spend MINIMAL time on this because jumping into development was more important to me than a good workflow.

## Basic Setup

The basic setup is dead simple. Because I don't want to use Parcel globally, I'll install it and all its plugins and dependencies, its transpilers and so on:

```bash
npm install parcel-bundler --save-dev
```

Yeah, that's it! And I'll go ahead and create a folder for my site called `site` and setup an NPM script so we can use the local install:

```bash
mkdir site
touch site/index.html
```
And the scripts:

```json
"scripts": {
  "start": "parcel site/index.html
}
```

Just running `npm start` will start your development flow where:

- everything is automatically watched
- files show up in `localhost:1234`
- compiled files are in `dist` folder


## SCSS compilation


I've used Parcel before which meant that I already knew it had great SASS/SCSS support. I remember the syntax better than LESS largely due to the fact that I worked on a couple of the Foundation projects and then I set it up at work so I worked with it more. Otherwise, I think the two are comparable (let's not start SASS/LESS wars).

The process is simple, install sass:

```
npm install sass --save-dev
```

And link to your scss file in your HTML:

```html
<html>
  <head>
    <link href="styles.scss" type="text/css" />
  </head>
</html>

```

You might have to restart parcel but it should "just work"TM. 

## Hmm, HTML templating?

Parcel doesn't include a templating engine. That's a GOOD thing. What it *does* include is PostHTML. 

Now, I was worried about this part but after doing some research, it's what made me use Parcel. PostHTML is an HTML post-processor. Kind of like PostCSS. 

Think of it as a tool that let's you do some really cool stuff with HTML. One of those things is using an `include` syntax via a plugin! WHAT?

I REALLY wanted my PHP-like `include` and that's what the `posthtml-include` plugin gives us but via a more HTML-like syntax like so:

```html
<include src="./partials/header.html"></include>
```

That was my WHOA moment. I looked at PostHTML plugins, and found a repository of AMAZING tools. I stuck to the `include` plugin because it was the easiest and simplest. It kept me away from doing things "too smartly". 

So to install it, you install the plugin

```bash
npm install posthtml-include --save-dev
```

and now you have to create your first piece of configuration. I want to point out that this is a config for `posthtml`, not for Parcel. Create a `.posthtmlrc.js` file and put this in there:

```js
module.exports = {
  plugins: {
    'posthtml-include': {
      root: __dirname + '/site',
    }
  }
}
```
This enables the plugin and tells you where the root of the project is.

## What else?

Well, nothing. With this simple setup, I've got SCSS compiling, basic HTML includes, file watching, server running, and basically no configuration apart from one plugin needing to know the root of the project.

I think next time I set this up, I'll try using [posthtml-modules](https://github.com/posthtml/posthtml-modules) which allows a sort of `transclusion` or "content projection" similar to what Angular and AngularJS do. Like so:

```html
<!-- index file -->
<module href="./module.html">
  Content to transclude
</module>

<!-- module file -->
Here is my special content:

<pre>
  <content></content>
</pre>

<!-- resulting index file -->

Here is my special content:

<pre>
  Content to transclude
</pre>
```

The other option is to use [posthtml-expressions](https://github.com/posthtml/posthtml-expressions) which does true templating; however, I'm still not a 100% sold on having a huge list of variables in my config. On the other hand, it'd bring us closer to 

## What about JavaScript?
And here's the thing...I realized I need some JS in the project after I got started. I need to have sticky dropdowns (click to reveal menu instead of hover), and a slider. Both are possible with CSS; however, not only is that a little beyond me, but I also think that would be rather unmaintainable.

So...I don't have to do much at this point except just include a JS script tag in the `index.html` file. And start coding. 

> Like this article? [Follow me on Twitter](https://twitter.com/antjanus) or checkout [my blog](https://antjanus.com)