Rick Carlino

Lead software developer and a co-founding member at FarmBot

Co-founder and Maker of Things at Fox.Build Makerspace in St. Charles, IL.

[ πŸ“¨ Newsletter ] [ πŸ’¬ Contact ] [ πŸ‘€ About ]


Really Simple Typescript Builds with Parcel

ParcelJS is a less noticed Javascript bundler that I increasingly incorporate into new projects.

I use it for a variety of reasons, most notably that:

  • Parcel supports Typescript and SASS without the use of plugins or configuration.
  • Parcel is zero config by default. Aside from a few command line arguments, it does only one thing.
  • It is easy to learn. The build system is easy to understand, both for you and the next developer on the project.
  • It is optimized for developer speed. Project setup is very fast. Compilation times are also fast.

For these reasons, Parcel is now my go-to utility for new projects. Below, I will cover the few steps a Typescript developer must take to start a new Parcel project.

Project Workflow

Here’s a common project workflow in ParcelJS:

  • Install Parcel
  • Create project files
  • Write Code
  • Compile, Serve, Auto-Reload πŸŽ‰

Step 0: Installation

This part is quick and not very interesting. The official documentation does a great job of explaining it. Please reference the documentation for the latest setup instructions. As of July 2018, setup amounts to not much more than a call to npm install -g parcel-bundler which gives you access to the parcel command line tool.

Step 1: Project Setup

Parcel is a zero config bundler. Note that this is not the same thing as a boiler plate. We still need to have a directory and file structure for the project1.

Create the project directory:

mkdir wow_parcel

Enter said directory:

cd wow_parcel

Create an empty package.json to bootstrap NPM:

npm init --yes

Add Typescript to package.json:

npm install typescript --save

Add React related modules:

npm install react react-dom --save

Add type information for non-typescript modules:

npm install @types/react @types/react-dom --save

Create an empty tsconfig.json for the project:

tsc --init

Create an empty HTML file to serve the app from:

touch index.html

Create an empty Typescript file for the app logic:

touch index.tsx

Project Structure

Our project folder now looks like this:

 FILENAME...             | ...WAS CREATED BY...
-------------------------|-----------------------------
wow_parcel/              |
  β”œβ”€ index.html          | <== `touch index.html`
  β”œβ”€ index.tsx           | <== `touch index.tsx`
  β”œβ”€ package.json        | <== `npm init`
  β”œβ”€ tsconfig.json       | <== `tsc --init`
  └─ node_modules/       | <== `npm install ___ --save`
     β”œβ”€ @types/react-dom |
     β”œβ”€ @types/react     |
     β”œβ”€ react            |
     β”œβ”€ react-dom        |
     └─ typescript       |

Project structure is ultimately up to the developer. The file structure above is a minimal example.

Step 2: Write Typescript

We can now write the application logic within index.tsx:

import * as React from "react";
import { render } from "react-dom";

function App = () => <div>Hey!</div>;

const el = document.querySelector("#app");

el && render(<App/>, el);

Here comes the interesting part. To add a resource to the page with parcel, you simply point a <script> tag to the *.tsx file:

<html>
  <body>
    <div id="app"></div>
    <!-- The script tag below is just a place holder.
         Parcel will perform magic to insert TSC output here: -->
    <script src="index.tsx"></script>
  </body>
</html>

Project setup is complete. We can now serve the app.

Step 3: πŸŽ‰Tada!

The parcel serve <file> command will run a webserver that (re)compiles our project in development mode:

parcel serve index.html

This will search index.html for <script> tags. It will infer the correct compilation strategy based on the file extension. This is also true for other types of compiled assets, such as SASS stylesheets.

Conclusion

Parcel is a sensible choice for Typescript codebases that do not have complex configuration needs. If you have been looking for alternative build systems that play well with Typescript, I hope you give it a look.


Footnotes

1: If you do want a boilerplate that has opinions about project structure, you may be better served by boilerplates like Typescript React Starter. Personally, I don’t like using boilerplates (other than the ones I make for my own use) because they are too prescriptive about how I should setup my projects. Create-Typescript-App is another one that I have seen referenced.