Bootstrapping a React TypeScript project with Parcel
Lea Rosema (she/her)

Lea Rosema (she/her) @learosema

About: Enterprisey Developer by day, creative coder by night. she/her

Location:
Hamburg, Germany
Joined:
Jul 6, 2017

Bootstrapping a React TypeScript project with Parcel

Publish Date: Sep 7 '18
88 8

With the Parcel bundler, you can bootstrap a React TypeScript project with (almost) zero configuration.

First, create a folder, cd into it, initialize NPM, install parcel and your React dependencies:

mkdir react-number-game
cd react-number-game
npm init -y
npm i parcel-bundler --save-dev
npm i react react-dom @types/react @types/react-dom --save
mkdir src
Enter fullscreen mode Exit fullscreen mode

Then, open your favorite code editor. Create a index.html file in your src directory. Modern editors like VSCode provide Emmet completion features. You can just enter a !, press the tab key and you get a basic html structure. Inside the body, add a root div element and a script tag with the reference to your entry index.tsx file:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>React TypeScript App</title>
</head>
<body>
  <div id="root"></div>
  <script src="./index.tsx"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Your minimal index.tsx file could look like this. There is no special TypeScript feature in there yet:

import * as React from 'react'
import { Component } from 'react'
import { render } from 'react-dom'
// import './index.css'

class App extends Component {
  render() {
    return (<h1>Hello World!</h1>)
  }
}

render(<App />, document.getElementById('root'))
Enter fullscreen mode Exit fullscreen mode

Finally, add a start command to your package.json:

{
  "name": "react-number-game",
  "version": "1.0.0",
  "description": "A number game in React",    
  "scripts": {
    "start": "parcel src/index.html",
  },
  "author": "Lea Rosema",
  "license": "MIT",
  "devDependencies": {
    // ...
  },
  "dependencies": {
    // ...
  }
}
Enter fullscreen mode Exit fullscreen mode

Then, you can start your application via npm start.

Additional project configuration

Production Build

Add a build command to your package.json and run npm run build:

{
  "scripts": {
    "build": "parcel build src/index.html",
  }
}
Enter fullscreen mode Exit fullscreen mode

Deployment

If you are using GitHub, you can easily deploy to gh-pages using the gh-pages npm package. I also use rimraf package to clean up the dist folder before building:

npm i rimraf gh-pages -D
Enter fullscreen mode Exit fullscreen mode

Add the following scripts to your package.json:

{
  "scripts": {
    "build": "parcel build --public-url . src/index.html",
    "clean": "rimraf dist/index.html dist/src.*.css dist/src.*.js dist/src.*.map",
    "predeploy": "npm run clean -s && npm run build -s",
    "deploy": "gh-pages -d dist"
  }
}
Enter fullscreen mode Exit fullscreen mode

The --public-url . parameter in the build step is important, because your project is deployed at https://username.github.io/projectname/ and the script is included with a slash by default (eg /src.0123abcdef.js). That would result in a 404 error.

TypeScript

You might need additional TypeScript configuration. Though, the minimal example works without any configuration. You can generate a tsconfig.json via node_modules/.bin/tsc --init. A nice minimal tsconfig.json could look like this:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "jsx": "react"
  }
}
Enter fullscreen mode Exit fullscreen mode

Autoprefixer

Install autoprefixer via npm i autoprefixer -D and add a .postcssrc:

{
  "plugins": {
    "autoprefixer": {
      "grid": true
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

SCSS

Just add a index.scss file to your project and import it into your entry index.tsx. Parcel automatically installs the node-sass precompiler for you.

.gitignore

Parcel builds the dist files in the related output folders dist and also has a cache folder .cache. I would recommend to add them to your .gitignore file:

dist/index.html
dist/src.*.js
dist/src.*.css
dist/src.*.map
.cache
Enter fullscreen mode Exit fullscreen mode

Result

See the resulting code at my react-number-game repository on GitHub.

Comments 8 total

  • smartmind25
    smartmind25Sep 7, 2018

    Nice

  • Robert Cooper
    Robert CooperSep 8, 2018

    Wow, it's much easier to get started using typescript with React than I thought!

  • Roger K.
    Roger K.Sep 8, 2018

    Just a thought Lea, but you may want to add the tag "Parcel" to you blog post. I follow parcel posts and just about missed this one. ;)
    Just a suggestion

  • Stephen Chiang
    Stephen ChiangOct 30, 2018

    I haven't tried this yet, but I know that my colleague was having to deal with really long compile times with this React-TypeScript project. Coming from Angular, I'm used to a couple seconds of live refresh time, but I just see him sitting there ready to pull his hair out and his dev time seriously cut. Do you experience any such phenomena with Parcel?

  • Dmytro Pylypenko
    Dmytro PylypenkoJan 22, 2019

    Parcel is fast and "zero-config" bundler.

    Thanks for the post Lea. Did you try parcel-plugin-typescript?

  • Luke Gibson
    Luke GibsonOct 14, 2019

    How would you get this project set up with TSlint?

Add comment