Refactoring code on my old side-project. In hope to learn and be more comfortable with TypeScripts and DUCKs redux file structure and feature-first file structure to build scalable project, I have started to refactor this simple addressBookApp which is the conventional functionality-first approach React app.
- create-react-app@2.1.0
- node.js@8.11.0
npm install
npm run start:dev
npm start
(to test) npm test
In order to convert existing react app to Typesciprt, it requires 2 changes:
- Add TypeSciprt Compiler (tsc) to building pipeline
- Change JS --> TS files
-
Install dependencies:
If you have CRA (react-scripts@2.1.0 or higher): Facebook Guide source
$ npm install --save typescript @types/node @types/react @types/react-dom @types/jest or $ npm install --save typescript @types/node @types/react @types/react-dom @types/jest
- Go to package.json and find
react-scripts:"...."
. If its version is lower than 2.1.0 then manually add "2.1.0" or higher. $ npm install
to reinstall.
- Go to package.json and find
$ npm install --save-dev typescript awesome-typescript-loader source-map-loader
- awesome-typescript-loader : webpack plugin to compile ts into js (like babel loader for babel)
- source-map-loader : adds source map support for debugging
$ npm install --save @types/react @types/react-dom
- installs type declaration files (.d.ts files) from @types for any library in use.
-
Configure TypeScript
Create a typescript config file to configure TypesScript (tsconfig.json in the root folder of the app)<!-- tsconfig.json file --> { "compilerOptions": { "outDir": "./dist/", // path to output directory "sourceMap": true, // allow sourcemap support "strictNullChecks": true, // enable strict null checks as a best practice "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 "moduleResolution": "node" // fixes csstype bug }, "include": [ "./src/**/*" // where ts files that needs to be compiled to js reside ] }
-
Setup Build pipeline
- Modify webpack.config.js file in order to add TypeScript compilation as a part of build process.
Required changes are:- To handle .ts & .tsx files
- Replace loader from babel-loader to awesome-typescript-loader
- Add source-map-loader
- Modify entry file from App.js to App.ts [optional].
<!-- webpack.config.js file --> module.exports = { // change to .tsx if necessary entry: './src/app.jsx', output: { filename: './dist/bundle.js' }, resolve: { // changed from extensions: [".js", ".jsx"] extensions: [".ts", ".tsx", ".js", ".jsx"] }, module: { rules: [ // changed from { test: /\.jsx?$/, use: { loader: 'babel-loader' } }, { test: /\.(t|j)sx?$/, use: { loader: 'awesome-typescript-loader' } }, // addition - add source-map support { enforce: "pre", test: /\.js$/, loader: "source-map-loader" } ] }, externals: { "react": "React", "react-dom": "ReactDOM", }, // addition - add source-map support devtool: "source-map" }
- Delete .babelrc and other Babel dependencies from package.json
- Above actions correctly set up build pipeline with TypeScript for handling transpilation. Build the app with this command -->
$ npx webpack
(installation of npx is required$ npm install -g npx
)
- Modify webpack.config.js file in order to add TypeScript compilation as a part of build process.
-
Min conversion
- Change
.js —> .ts
or.jsx --> .tsx
extensions in files - Import React from react —>
import * as React from react
- Add types to class declararion of
React.Component
by the end oferact.Component<any, any>
. <property type, state type>
- Change
-
Add types
- Add types for properties and state for the Component
- Add types to params
-
Convert the entire codebase
After each step always bundle the app by running
$ npx webpack
- Add TypeScripts
- Change from functionality-first to feature-first
- Separate one file into Container and Presentational Component
- Apply DUCKs for Redux
- Testing in Typescript
- Add optimisation
- Code Splitting
- SSR