The feeling, when you react, script and pack. Why am I writing this At the time of writing this article, the popularity of has already shot off the roof, that of is on the rise and it is safe to say that is the most preferred modern module bundler for an application. However, there is still an underlying dearth of a good example of the best possible way to start a project in with and . Having said that, there are good resources out there if you want to use cli or any other react starter kit out there. But there are very few ones if you want to have control over the configurations of your application. React Typescript Webpack React Typescript Webpack create-react-app The downside of using a cli like create-react-app are that you have to rely on the following tools the same way create-react-app relies on Webpack Babel PostCSS w/ Autoprefixer Jest Flow (optional) If you strongly dislike any one of the above, you are going to have a hard time accepting it. lives upto its promise of ‘ because you simply cannot configure this tool. It provides a way of ejecting the tooling where you can let go of create-react-app if you want to extend the configuration further but why should I? Wouldn’t it be much more easier if I would have handled the configuration from the beginning in the first place? Moreover, once you eject, there is going to be an increase in the dependencies of your project, half of which you might not even need. Having said all that, it is probably the best react toolkit out there to get your project started if you are looking for one as a beginner or for a small to medium level project. create-react-app no build configuration’ You may find this article helpful if you want to set up a project with the following things: — The primary front-end framework React — The primary language that compiles to javascript Typescript — The application bundler. Webpack — The server which will host the react application Express — Something which will serve and load all your code changes you make while the server is running to the browser without you having to stop and run your app again. Hot Module Reload Let the reacting, scripting and packing begin! Before we begin, make an empty folder somewhere in your drive to begin afresh. If you are using a windows machine, go to your command line terminal and type the following three commands. mkdir react-ts-webpackcd react-ts-webpackcode . the last command will open the recently created empty folder as a project in Visual Studio Code, a fairly popular editor and you are most likely to have it. Feel free to open it in your favorite editor if you do not have it. So, as per popular tradition when you create a new project, initialize the npm in our project by typing the following line in the terminal. npm init -y Now we are going to create a few files and folders that are required to set up the project. So, on the root of your folder create the following files/folders. Create file : webpack.config.js This is for webpack configurations Create file : tsconfig.json This is for typescript configurations Create file server.js: This is your server to start up the application Create folder src. Create folder inside app src. Create a file inside and folder index.html app components Create files inside and inside App.tsx app Hello.tsx components So the folder structure of the application looks something like this |-src|-app|-components|-Hello.tsx|-App.tsx|-index.html|-package.json|-package-lock.json|-server.js|-tsconfig.json|-webpack.config.js Let the downloading begin! Now we are going to download our production and development dependencies. Download production dependencies npm i react react-dom express typescript --save Download development dependencies npm i @types/react @types/react-dom webpack webpack-cli ts-loader webpack-dev-middleware webpack-hot-middleware html-webpack-plugin source-map-loader -D Congratulations! we are almost halfway there without writing a single piece of code. Let’s Code! So, here are the contents of the files you just created. You can paste them onto your relative project from here (gist link is embedded in the title of the file) or type along. index.html : tsconfig.json : : webpack.config.js Let’s react a bit! Let us write a typical react component, after all this is the code that you will and should be concentrating on after you have completed the set up. So, either you can write along or paste the code as you like. Hello.tsx: import * as React from 'react'; interface IProps {compiler: string,framework: string,bundler: string} export class Hello extends React.Component<IProps, {}> {render() { return <h1>This is a {this.props.framework} application using {this.props.compiler} with {this.props.bundler}</h1>}} : App.tsx import * as React from 'react';import * as ReactDOM from 'react-dom';import { Hello } from './components/Hello'; ReactDOM.render(<Hello compiler="Typescript" framework="React" bundler="Webpack" />, document.getElementById('root')); Let’s get packing! In case you are not familiar with webpack, a brief about the options is provided below. Feel free to skip it in case you are already aware of this stuff. : The way webpack works is you provide it an entry and it claws its way up to build your app looking into what your entry imports and creates a dependency graph accordingly, the more properties you provide to this object, the same amount of bundles it is going to create, so by looking into the and config, you can guess that it is going to create and . The reason for having separate bundles is because your react and react-dom code is unlikely to be changed, so having them as separate bundle (called vendor) makes sense for your browser to be able to cache it for performance. The webpack-hot-middleware/client in the app property is present for enabling the app code to be live reloaded. entry entry output app.bundles.js vendor.bundles.js Webpack looks at this configuration when it has to emit the bundled code from your app to the disk. is the output directory for the code to be written and is as the name suggests the name of the file to be given to the output code. : output path filename Webpack looks at this config to add certain tools for development. Here source-map is added so that the code is source-mapped in the browser so that debugging can be made easy in development time. devtool: : Webpack looks here to decide whether to consider this file for bundling or leave it, so in our app it considers files with extensions ‘ ’, ‘ ’, ‘ ’, ‘ ’, ‘ ’ for bundling. resolve js jsx json ts tsx This configuration enables webpack to load a particular file when requested by the app with the help of loaders. In our app we are using ts-loader and source-map-loader. source-map-loader is already covered above. So, without , webpack would not be able to understand this import in the file since component is a ‘ ’ file understood by your editor but not by webpack when the import actually occurs. module: ts-loader App.tsx Hello tsx import { Hello } from './components/Hello'; : Webpack cannot do everything and it is kind of wrong for us to expect it to do everything. So, it overcomes its limitation by providing plugins to let it be extended beyond its capabilities like the creates a template file to be served to the browser from our file in the folder and the plugin enables our code to be hot reloaded removing the need to stop the server and run it again every time a change is made to the app. plugins html-webpack-plugin index.html src HotModuleReplacement Let’s Build! You can now actually manually build your application. We will get to building automatically before running our server later. but for now if you want to take a look at your efforts until now, just add a ‘build’ script to your package.json file and execute the webpack command. : package.json ...scripts: {... ...}... "build": "./node_modules/.bin/webpack", If you go to the terminal and run this command, you can look at your bundled application in the dist folder. Run this in your terminal: npm run build Output in the terminal: npm run build bundled code Let’s Express! If you do not want to use express to run a server for you react application to be served, you can use which takes care of it and you do not have to write a server yourself but if you want to have the flexibility of a custom server for you to write middlewares, handle routes and modify requests and responses then it is recommended that you write your own server. At the time of writing this article, has no new features planned and is in maintenance only mode. webpack-dev-server webpack-dev-server https://www.npmjs.com/package/webpack-dev-server server.js: const path = require('path'),express = require('express'),webpack = require('webpack'),webpackConfig = require('./webpack.config.js'),app = express(),port = process.env.PORT || 3000; app.listen(port, () => { console.log(`App is listening on port ${port}`) }); app.get('/', (req, res) => {res.sendFile(path.resolve(__dirname, 'dist', 'index.html'));}); let compiler = webpack(webpackConfig);app.use(require('webpack-dev-middleware')(compiler, {noInfo: true, publicPath: webpackConfig.output.publicPath, stats: { colors: true }}));app.use(require('webpack-hot-middleware')(compiler));app.use(express.static(path.resolve(__dirname, 'dist'))); Now you can go to your package.json and add the start script "start": "npm run build && node server.js" Let’s reload! Once you run the server by running ‘ ’ in the terminal, the webpack-dev-middleware and webpack-hot-middleware should take care of hot module replacement but that is not the case. npm start You may notice that after you make a change, webpack duly compiles and emits the changed code but it only takes effect when you refresh your browser. That is not what we signed up for. The browser should have refreshed after re-building the changed component. HMR in action In order to fix this, we need to change our ‘ a bit App.tsx’ import * as React from 'react';import * as ReactDOM from 'react-dom';import { Hello } from './components/Hello'; declare let module: any ReactDOM.render(<Hello compiler="Typescript" framework="React..." bundler="Webpack" />,document.getElementById('root')); if (module.hot) {module.hot.accept();} So basically we are saying our app to accept the hot reloaded changes made by webpack. The declaration part is needed because ‘hot’ property is not present by default on the ‘ ’ object and we need to ask typescript to allow it. module Once you restart your server after this change, it works as expected. HMR Fixed In case you want to view the complete boiler plate create. You can clone/download from this repository _react-ts-webpack-boilerplate - This is the ultimate lightweight boilerplate needed for a React application using…_github.com saurabhpati/react-ts-webpack-boilerplate I will try to add code splitting to further increase the efficiency of the build process and will be happy to receive any feedback regarding this post.
Share Your Thoughts