This is a three part series for setting up and getting started with ReactJS and Typescript. The subsequent parts will show how to create a GitHub repository for the code and then use the same GitHub repository to kick start new ReactJS-TypeScript based developments.
The first part of the series will show how to setup the development environment for ReactJS with Typescript.
The later parts in the series are…
GitHub Repository - https://github.com/manish-patil/react-typescript
Introduction
After working on JavaScript frameworks like ExtJs, Angular 1.x and others, I thought of exploring newer frameworks like Angular 2.0 and ReactJS.
Now from my experience, starting with ReactJS afresh, was easier said than done, at times it was more frustrating than anything. Days spend, trying to figure out what was going on…..
Too many new things, too many choices, too many decisions to make, none of them easy, new techniques to see, learn, things to unlearn, new tools, new languages to choose between like TypeScript or Babel or something else. New ways of building code – understanding transpilation. It was almost like a never ending nightmare. But when it started unraveling, it all become clearer and easier.
But at the end of it all, it turns out that there is a lot of work to set up the code and starting the development process. It is not like other frameworks where we can start seeing the results almost as soon as we start.
So the first part of this post is just to detail out all that I have found in the course of this epic journey. Firstly, so that I don’t forget, because there are a lot of steps to remember and secondly, it takes a lot of time to setup a very simple workspace if you choose to do it all from scratch, later the code will be moved to GitHub, so that we can use that Github repository to setup new code quickly.
In the second part of the post, I would like to share a small GitHub repository or repo for short, I would be creating for hosting the code created in this post (Part I). This would include all the steps on how to use Git, its commands, creating branches, doing commits and then finally how to push code to GitHub. This is a reference article, to show how to use Git and GitHub, and is not required for starting the development.
In the third part, I would show how to use the GitHub repo, clone it locally, checkout specific branches - to help anyone to quickly setup this very basic codebase (created in Part I) locally and use it as a basis for bigger applications.
So before I go ahead, I’d like to summarize some of the questions I had when I started and the best answers, I think I could come up with.
Q. Angular 2.0/4.0 or React?
Ans. React, why not!!!
Q. React with TypeScript or Babel?
Ans. The internet is filled with React technical blogs explained with Bable. But naturally, I choose TypeScript – for three reasons:
- There is very little support on the net for React and Typescript.
- So that I don’t have to learn TypeScript for Angular 2.0+
- I think it would be better to support large projects with Typescript.
But only time will tell who will win – Google supported TypeScript or ECMA 6+ Babel.
Disclaimer: A very important thing to note here is, things are moving very fast, I don’t even know if this post would be valid by the time it goes live! I mean there are posts on the internet, which were written in 2016 or earlier, technically either won’t be optimal for today's work environments or won’t work without extensive updates.
So Enough Talk, Let's Dive In
I - Download and install the following tools:
VS Code is not required, any other text editor or JavaScript IDE can be used, like WebStrom or Visual Studio. For all our command line needs, we can use Git Bash. We would need Git Bash for the next parts any way.
II - Let's create a folder react-typescript. Fire Git Bash and navigate to the newly created folder. In Git Bash, type the command:
npm init -–force
This command will create a default node package.json file. The file contains all the config information the application requires like the general descriptions and node modules (otherwise called - packages or dependencies), which are required by the application - the dependencies can either be application dependencies or development only dependencies.
III – Install the required “development only” node packages using the following command. These Node Packages support development, and are not deployed to production.
npm install --save-dev typescript webpack ts-loader
IV – Install the required “application only” node packages using the command:
npm install --save react react-dom
The above commands will create a node_modules folder and install the said node modules locally to the folder, i.e., the modules will not be available outside the react-typecript folder for executions, and we will soon see what this means. This will also update the package.json file as below, adding the devDependencies
and dependencies
nodes.
{
"name": "react-typescript",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"ts-loader": "^2.3.7",
"typescript": "^2.5.3",
"webpack": "^3.6.0"
},
"dependencies": {
"react": "^16.0.0",
"react-dom": "^16.0.0"
}
}
V – Now as our dependencies are installed, let's try writing some familiar code, JavaScript and HTML code. To do this, let's open VS Code and load the project. A short hand for opening VS Code from the current location at Git Bash or any terminal would be typing the command:
code .
In VS Code - node_modules folder and package.json file would already be present.
Now let's create our applications entry point index.html at the root of the react-typescript folder. Add the following code to the 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>Document</title>
</head>
<body>
<div id="main"></div>
<script src="dist/bundle.js"></script>
</body>
</html>
This is a very basic HTML file, with two noticeable elements.
- The
div
named main
which will be our ReactJS application entry point. - A
script
tag, with not yet created file dist/bundle.js as src
.
VI – Now let's create our first ReactJS components. In VS Code, create a folder called src at the root of the react-typescript folder. Inside the src folder, create a new file index.tsx. The file will contain the following code:
import * as React from "react";
import * as ReactDOM from "react-dom";
class Main extends React.Component<any, any>{
constructor(props: any) {
super(props);
};
render() {
return(
<div><h1>Hello World!!!</h1></div>
);
};
}
ReactDOM.render(<Main/>, document.getElementById("main"));
The code is not JavaScript but is Typescript, Typescript code is not meant to be executed in the browser, but has to be converted/transpiled to JavaScript before getting executed on any browser.
In the next steps, this code and all its dependencies will be transpiled into JavaScript to a file dist/bundle.js, which is referenced in the index.html file.
The code is creating a React.Component
called Main
, which will simply render Hello World!!!
. The Main
component will be loaded inside the div
called main
which we have added to the index.html file in step V, using the ReactDOM
library.
VII – Create a new file tsconfig.json at the root of the react-typescript folder. This json file will hold the TypeScript compilerOptions
against which we would transpile our code for distribution, using webpack - a JavaScript module bundler. Add the below content to the file - tsconfig.json.
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"jsx": "react"
}
}
VIII – Create a new file webpack.config.js parallel to the tsconfig.json.
var path = require("path");
module.exports = {
entry: ["./src/index.tsx"],
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
loaders: [{
test: /\.tsx?$/,
loader: "ts-loader"
}]
}
};
The entry point for webpack is the src/index.tsx file create in step VI.
The requested output from webpack is a file - bundle.js to be created in the dist folder in the current root. The same file - dist/bundle.js, is referenced in the index.html file.
IX – Now with a basic code and configuration setup ready, the next step would be to ask webpack to build the code and create the distributable code.
To do this, we need to execute webpack. As mentioned in step IV, we have installed our development dependencies locally to the current folder. Hence, we cannot execute webpack with a simple global command like:
node webpack
But we can execute webpack, if we pass the location of webpack from within the node_modules folder to node like so:
node node_modules/webpack/bin/webpack.js
Like seen in the above image, the command node node_modules/webpack/bin/webpack.js will initiate webpack
, then using ts-loader
via tsconfig.json will transpile index.tsx, the entry point mentioned in the webpack.config.js.
Now executing the above command to build the code is not the most optimal way, but there is another way - in the package.json file, locate “scripts
” node and add a key value pair of "build
": "webpack
" to it. To execute this script in Git Bash, execute the below command, the same can be done in VS Code terminal. The difference between the earlier command and this one is that, with this command, it is the node package manager which locates webpack for you within the installed node packages, whereas earlier, you were explicitly asking node to execute a package at a location.
npm run build
Either way, the result will be the same - the output will be a JavaScript file dist/bundle.js.
X – Locate index.html and open it in any browser.
Here, we have our first ReactJS – TypeScript application.
XI – Above, we have only one component <Main />
. In a ReactJS application, there is primarily one Layout level component, in our case <Main />
and then there are child components loaded inside of the Layout
component. Let's create and add a child component to the application. In the src folder, create a child folder components and then add a new file Hello.tsx to it. The file will contain the following code:
import * as React from "react";
export default class Hello extends React.Component<any, any>{
constructor(props: any){
super(props)
}
render() {
return (
<div style={{backgroundColor: 'Gray'}}>
<h1>Hello World!!!!</h1>
</div>
);
}
}
Unlike the Main
component, the Hello
component doesn’t have a reference to React-DOM. To consume the Hello
component in the Main
component, we import a reference to Hello
in Main
and replace the code <div><h1>Hello World!!!</h1></div>
with <Hello />
. The updated index.tsx file would look like below:
import * as React from "react";
import * as ReactDOM from "react-dom";
import Hello from "./components/Hello";
class Main extends React.Component<any, any>{
constructor(props: any) {
super(props);
};
render() {
return(
<Hello/>
);
};
}
ReactDOM.render(<Main/>, document.getElementById("main"));
After executing the command npm run build
again, the index.html looks like below. Interestingly there are no config changes required, no script
tags added to the index.html file, nothing.
By now, you must have thought – all this work for a simple HelloWorld
application? Well yes, this is the initial setup required for these kind of new frontend applications using Babel or Typescipt. In the next post in the series, I would try to show how this code can be published to GitHub from your local computer, and then the same repo can be used to startup new ReactJS applications without much hassle.