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
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>
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'))
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": {
// ...
}
}
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",
}
}
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
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"
}
}
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"
}
}
Autoprefixer
Install autoprefixer via npm i autoprefixer -D and add a .postcssrc:
{
"plugins": {
"autoprefixer": {
"grid": true
}
}
}
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
Result
See the resulting code at my react-number-game repository on GitHub.
Top comments (7)
Wow, it's much easier to get started using typescript with React than I thought!
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?
Nice
Parcel is fast and "zero-config" bundler.
Thanks for the post Lea. Did you try
parcel-plugin-typescript?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
Thank you! I added the tag :)
How would you get this project set up with TSlint?