Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

Commit

Permalink
📝 Readme small updates and fixes
Browse files Browse the repository at this point in the history
- block codes
- white space unification
- headers are now grouped by level
- minor typos
- shortened direct webpack execution with npx tool
  • Loading branch information
peterblazejewicz committed Feb 28, 2018
1 parent 4515e2f commit f66eeff
Showing 1 changed file with 39 additions and 35 deletions.
74 changes: 39 additions & 35 deletions README.md
Expand Up @@ -4,11 +4,12 @@ This walkthrough illustrates how to adopt TypeScript in an existing React/Babel/

If you are starting a new React project instead of converting one, you can use [this tutorial](https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/tutorials/React.md).

Adopting TypeScript in any project can be broken down into 2 phases,
* Adding TypeScript compiler (tsc) to your build pipeline.
* Converting JavaScript files into TypeScript files.
Adopting TypeScript in any project can be broken down into 2 phases:

# Understand the existing JavaScript project
* Adding TypeScript compiler (tsc) to your build pipeline.
* Converting JavaScript files into TypeScript files.

## Understand the existing JavaScript project

Before we dive into TypeScript adoption, let's take a look at the structure of the TicTacToe app. It contains a few components and looks like below with or without TypeScript.

Expand All @@ -18,7 +19,7 @@ Before we dive into TypeScript adoption, let's take a look at the structure of t

As shown in `package.json`, the app already includes React/ReactDOM, Webpack as bundler & task runner, and [babel-loader](https://github.com/babel/babel-loader) Webpack plugin to use Babel for ES6 and JSX transpilation. The project has the below overall layout before we adopt TypeScript:

```
```txt
TicTacToe_JS /
|---- css/ // css style sheets
|---- src/ // source files
Expand All @@ -29,49 +30,50 @@ TicTacToe_JS /
|---- restartBtn.jsx // RestartBtn React component
|---- .babelrc // a list of babel presets
|---- index.html // web page for our app
|---- package.json // node package configuration file
|---- package.json // node package configuration file
|---- webpack.config.js // Webpack configuration file
```

# Add TypeScript compiler to build pipeline
## Add TypeScript compiler to build pipeline

## Install dependencies
### Install dependencies

First off, open terminal and `cd` to the `TicTacToe_JS` folder. Install dependencies in `package.json`.

```
```sh
cd TicTacToe_JS
npm install
```

Additionally, install TypeScript (2.3 or higher), [awesome-typescript-loader](https://www.npmjs.com/package/awesome-typescript-loader) and [source-map-loader](https://www.npmjs.com/package/source-map-loader) as dev dependencies if you haven't. awesome-typescript-loader is a Webpack plugin that helps you compile TypeScript code to JavaScript, much like babel-loader for Babel. There are also other alternative loaders for TypeScript, such as [ts-loader](https://github.com/TypeStrong/ts-loader). source-map-loader adds source map support for debugging.

```
```sh
npm install --save-dev typescript awesome-typescript-loader source-map-loader
```

Get the type declaration files (.d.ts files) from [@types](https://blogs.msdn.microsoft.com/typescript/2016/06/15/the-future-of-declaration-files/) for any library in use. For this project, we have React and ReactDOM.
Get the type declaration files (.d.ts files) from [@types](https://blogs.msdn.microsoft.com/typescript/2016/06/15/the-future-of-declaration-files/) for any library in use. For this project, we have React and ReactDOM.

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

If you are using an older version of React/ReacDOM that are incompatible with the latest .d.ts files from @types, you can specify version number for `@types/react` and `@types/react-dom` in `package.json`.

## Configure TypeScript
### Configure TypeScript

Next, configure TypeScript by creating a `tsconfig.json` file in the `TicTacToe_JS` folder, and add,
Next, configure TypeScript by creating a `tsconfig.json` file in the `TicTacToe_JS` folder, and add,

```
```json
{
"compilerOptions": {
"outDir": "./dist/", // path to output directory
"sourceMap": true, // allow sourcemap support
"strictNullChecks": true, // enable strict null checks as a best practice
"module": "es6", // specifiy module code generation
"module": "es6", // specify module code generation
"jsx": "react", // use typescript to transpile jsx to js
"target": "es5", // specify ECMAScript target version
"allowJs": true // allow a partial TypeScript and JavaScript codebase
"allowJs": true // allow a partial TypeScript and JavaScript codebase

},
"include": [
"./src/"
Expand All @@ -81,14 +83,14 @@ Next, configure TypeScript by creating a `tsconfig.json` file in the `TicTacToe_

You can edit some of the options or add more based on your own need. See more full [compiler options](https://www.typescriptlang.org/docs/handbook/compiler-options.html).

## Set up build pipeline
### Set up build pipeline

To add TypeScript compilation as part of our build process, you need to modify the Webpack config file `webpack.configure.js`. This section is specific to Webpack. However, if you are using a different task runner (e.g. Gulp) for your React/Babel project, the idea is the same - replace the Babel build step with TypeScript, as TypeScript also offers transpiling to lower ECMAScript versions and JSX transpilation with a shorter build time in most cases. If you wish, you can also keep Babel by adding a TypeScript build step before Babel and feeding its output to Babel.
To add TypeScript compilation as part of our build process, you need to modify the Webpack config file `webpack.configure.js`. This section is specific to Webpack. However, if you are using a different task runner (e.g. Gulp) for your React/Babel project, the idea is the same - replace the Babel build step with TypeScript, as TypeScript also offers transpiling to lower ECMAScript versions and JSX transpilation with a shorter build time in most cases. If you wish, you can also keep Babel by adding a TypeScript build step before Babel and feeding its output to Babel.

Generally, we need to change `webpack.config.js` in a few ways,

1. Expand the module resolution extensions to include `.ts` and `.tsx` files.
2. Replace `babel-loader` with `awesome-typescript-loader`.
2. Replace `babel-loader` with `awesome-typescript-loader`.
3. Add source-map support.

Let's modify `webpack.configure.js` as below,
Expand All @@ -108,7 +110,7 @@ module.exports = {
rules: [
// changed from { test: /\.jsx?$/, use: { loader: 'babel-loader' } },
{ test: /\.(t|j)sx?$/, use: { loader: 'awesome-typescript-loader' } },
// addition - add source-map support
// addition - add source-map support
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
]
},
Expand All @@ -127,11 +129,13 @@ Note that if you plan to adopt TypeScript in the entry file, you should change `

You now have the build pipeline correctly set up with TypeScript handling the transpilation. Try bundling the app with the following command and then open `index.html` in a browser,

```sh
npx webpack
```
node ./node_modules/webpack/bin/webpack.js
```

# Transition from JS(X) to TS(X)
> We are assuming you are using `npx` addition for `npm` to [execute npm packages directly](http://blog.npmjs.org/post/162869356040/introducing-npx-an-npm-package-runner)
## Transition from JS(X) to TS(X)

In this part, we will walk through the following steps progressively,

Expand All @@ -141,7 +145,7 @@ In this part, we will walk through the following steps progressively,

While you get the most out of TypeScript by fully adopting it across your codebase, understanding each of the three steps comes in handy as you decide what to do in case you have certain part of your JavaScript codebase you want to leave as-is (think legacy code that no one understands).

## Minimum transition steps
### Minimum transition steps

Let's look at `gameStateBar.jsx` as an example.

Expand All @@ -153,21 +157,21 @@ On line 3 `export class GameStateBar extends React.Component {`, change the clas

By now, awesome-typescript-loader should be able to successfully compile this TypeScript component to JavaScript. Again, try bundling the app with the following command and then open `index.html` in a browser,

```
node ./node_modules/webpack/bin/webpack.js
```sh
npx webpack
```

## Add types
### Add types

The more type information provided to TypeScript, the more powerful its type checking is. As a best practice, we recommend providing types for all declarations. We will again use the `gameStateBar` component as an example.

For any `React.Component`, we should properly define the types of the property and state object. The `gameStateBar` component has no properties, therefore we can use `{}` as type.
For any `React.Component`, we should properly define the types of the property and state object. The `gameStateBar` component has no properties, therefore we can use `{}` as type.

The state object contains only one property `gameState` which shows the game status (either nothing, someone wins, or draw). Given `gameState` can only have certain known string literal values, let's use [string literal type](https://www.typescriptlang.org/docs/handbook/advanced-types.html) and define the interface as follow before the class declaration.

```ts
interface GameStateBarState {
gameState: "" | "X Wins!" | "O Wins!" | "Draw";
gameState: "" | "X Wins!" | "O Wins!" | "Draw";
}
```

Expand Down Expand Up @@ -209,19 +213,19 @@ private handleRestart(e: Event) {...}

Again, try bundling the app with the following command and then open `index.html` in a browser,

```
node ./node_modules/webpack/bin/webpack.js
```sh
npx webpack
```

## Adopt TypeScript in the entire codebase
### Adopt TypeScript in the entire codebase

Adopting TypeScript in the entire codebase is more or less repeating the previous two steps for all js(x) files. You may need to make changes additional to what is mentioned above while converting perfectly valid JavaScript to TypeScript. However the TypeScript compiler and your editor (if it has TypeScript support) should give you useful tips and error messages. For instance, parameters can be optional in JavaScript, but in TypeScript all [optional parameter](https://www.typescriptlang.org/docs/handbook/functions.html) must be marked with `?`

You can see the fully converted TicTacToe project in the `TicTacToe_TS` folder. Build the app with,

```
```sh
npm install
node ./node_modules/webpack/bin/webpack.js
npx webpack
```

Run the app by opening `index.html`.

0 comments on commit f66eeff

Please sign in to comment.