Getting Started with ReactJS, Typescript, and Webpack

Recently at work, I’ve been working on transitioning our web application from Typescript, Angular, Bower and Gulp to Typescript, ReactJS, NPM, and Webpack. After scouring the internet, I found lots of articles documenting how to get started with React and Webpack, but very few integrating Typescript as well. In this tutorial, I want to briefly describe these technologies and how to get started using all 3 of them together. So let’s get started!

For those of you who want to dive in and see the final version of the code, check it out here!

Brief prelude about why ReactJS, why Typescript, and why Webpack

Before I get into meat of this tutorial, I want to briefly describe these technologies and why you might want to use them together.

ReactJS is a library released by Facebook and unlike other JavaScript frameworks out there (i.e. Angular, Backbone, Ember, etc), it’s goal is to simply represent the “View” layer in the traditional Model View Controller (MVC) paradigm. Having used other frameworks at my work place in the past, including Backbone / Marionette and Angular, I have to say that using React has been refreshingly simple and a joy to write code with. In particular, I’ve really enjoyed how I can describe how the UI should be and leave the DOM re-rendering and browser idiosyncrasies to React’s Virtual DOM and diff’ing algorithm.

Typescript is developed and maintained by Microsoft and it’s best described as JavaScript with an optional Type system. It’s a complete superset of JavaScript, which means that every bit of JavaScript code you’ve written is already valid Typescript code. I was initially skeptical about using Typescript since it adds another layer into our technology stack, but having used it daily for the past year has convinced me of how awesome it is. The type system makes your code sturdier and more resilient because you’ll get to detect errors during compilation as opposed to runtime. Many popular 3rd party libraries have released Typescript definition files via Definitely Typed which means that you can download and use these definition files with Typescript. Many text editors and IDE’s (i.e. Atom, Eclipse, etc) can leverage these definition files to allow awesome features like autocomplete and compilation error detection.

Webpack is a module bundler, and this simply means that it can take many different JavaScript files / modules and efficiently combine them together into one final JavaScript file. Having one file as opposed to many files allows your web application to load more quickly since there’s fewer <script> tags that need to be loaded. JavaScript’s lack of a formal module construct has been a major pain point for many developers, but luckily, as the web developer community has moved towards using NPM as the JavaScript package manager, the CommonJS module format has become a standard as well (as a quick aside, with the release of ES2015, JavaScript now has a standard way to create, import, and export modules). If you write your code using the CommonJS format, Webpack can recursively go through all of the require and export statements to build out your web application’s dependency tree. Having used Webpack for a bit, I’ve found that while it can be daunting to understand all the available options to configure it, you’ll most likely just need the standard pieces of it and in that regard, it’s fairly simple to use.

Getting Started

I’m going to assume that you are using a Mac and that you have NPM installed (my recommendation is to use Homebrew and follow these instructions: https://nodejs.org/en/download/package-manager/#osx). For this tutorial, I’ll first describe the process to integrate Typescript with Webpack, and once we have a working version of that, I’ll throw in React so that we have all 3 pieces working together.

Part 1 — Typescript and Webpack

Let’s go ahead and open a terminal window, create a new project directory, and cd into it.

I named my project “typescript-react-webpack” but feel free to name yours differently!

Next, let’s create the following directory structure inside of the project.

At the root of your project directory, run “npm init -y” which is a NPM command that creates a boilerplate package.json file for you.

Using your text editor / IDE of choice, let’s clean up the package.json file a little bit.

In case you’re wondering, I’m using Vim to edit my package.json

Next, we’ll install Typescript and Webpack. Notice that I installed Typescript and Webpack with the “ — save-dev” flag, which simply means that I want to save these packages as developer dependencies (i.e. these are packages that the actual web application doesn’t need but are used by developers to produce the final web application).

Here’s how my package.json file and root directory look right now.

My package.json now includes Typescript and Webpack
My root directory now includes a node_modules directory containing Typescript and Webpack

In order to set up Webpack, I’ll add a webpack.config.js file in the root directory and it’ll have the following content:

Next, let’s install ts-loader by executing npm install ts-loader (remember to save it as a developer dependency).

We’re almost there — now we just need to create a couple of files: index.html, src/app.ts, and src/some_module.ts

We’ll also want to modify our package.json to include a NPM script which runs Webpack for us. Here’s how my package.json file and project directory look right now.

Added a “build” script to the package.json file

We’re finally here — the moment of truth! If we run “npm run build” in our root directory, we should see Webpack do its magic and produce a bundle.js file in the build directory. If we open the index.html file and look at the console, we should see our greeting.

Woohoo! The obligatory Hello World!

Part 2 — ReactJS, Typescript, and Webpack

Now that we have a Typescript and Webpack integrated, let’s go ahead and throw ReactJS into the mix as well. Let’s first npm install ReactJS as a dependency.

We need both react and react-dom

Since we’re using a 3rd party library with Typescript, we’re going to need to npm install Typings as well. You might be asking, “what is Typings?” Remember earlier how we described Definitely Typed as a repository for 3rd party Typescript definition files? Typings is simply the tool we use to manage all of the Typescript definition files. It’ll allow us to easily download and use all of our 3rd party Typescript definition files. You might notice that if you install Typings with “ — save-dev”, the terminal will output this message — I’ll leave it up to you whether you want to install Typings globally or not.

Here’s how our package.json file looks now:

Notice react and react-dom are in the “dependencies” block

Let’s download the Definitely Typed files for React and ReactDOM. We’ll use Typings to do the installation and we’ll take a look at our current directory structure:

A couple of things to notice:

  1. Because we didn’t install Typings globally, we had to prefix the command with where the Typings module is located: node_modules/.bin/typings.
  2. The “save” flag indicates that we want to save the React and ReactDOM definition files.
  3. Notice that our directory now has a typings directory as well as a typings.json file. The typings.json file specifies all of the definition files we have installed, and the typings directory contains the actual definition files.
  4. If you look closely, you’ll notice that the typings directory seems to contain 2 identical sets of definition files for React and ReactDOM. And that’s actually the case — but we’ll go ahead and set up a Typescript configuration file next that will exclude 1 of the 2 sets of definition files.

Now that we’re trying to use React with Typescript, we should create a Typescript configuration file — be sure to name it tsconfig.json. We could have set this up in Part 1 as well, but Typescript knows that if it can’t find a tsconfig.json file in our root directory, it’ll just use a default configuration.

A couple of things to note here:

  1. Make sure that tsconfig.json is located in the root directory.
  2. If you want to learn more about the tsconfig.json file, check this and this out. Of particular importance to us is the “jsx” key which tells Typescript to accept React’s JSX syntax whenever we create a file with a “.tsx” extension.
  3. Notice that we’re specifying files and directories to include from going through the Typescript compiler. Like we mentioned before, we’re going to ignore one set of the definition files for React — all of the browser related ones.

Since we’re using React now, let’s rename our src/some_module.ts file to src/Hello.tsx, and create a simple Hello component:

Let’s also rename our src/app.ts file to src/app.tsx, and change the content to the following:

Since we’re injecting our rendered Hello component into the DOM, we’ll need to modify our index.html file as well.

We’ve renamed our application’s entry point, which means we’ll need to modify our webpack.config.js file as well. It’s a minor change — we just need to change it to the correct file extension.

If you’ve followed all these steps, you should have the following in your root directory:

And if you run “npm run build” in your terminal again, you should see Webpack do its thing and generate a new bundle.js file. If we open our index.html in the browser, you’ll see the fruits of your labor!

Woohoo! Typescript, React, and Webpack all integrated together!

Conclusion

Hopefully you’ve found this tutorial helpful for getting you started using these 3 technologies together. There’s tons more you can do (i.e. use webpack-dev-server, set up source maps in Typescript, etc) but I’ll leave it for you to continue exploring!