Create a new directory for the project and then go inside it.
mkdir sunflora
cd sunflora
Initialize git to keep tracking changes we’re gonna make.
git intit
Add package.json
file for package management.
touch package.json
And then, add the following content to just created package.json file.
{
"license": "MIT"
}
Add two most important packages for any ReactJS project.
yarn add react react-dom
yarn add -D @types/react @types/react-dom
As we’re gonna use Typescript, we need to add those typing packages as devDependencies.
One more thing that, we don’t need upload a huge node_modules
to the git repository.
We ignore it by adding to .gitignore
file.
echo "node_modules" >> .gitignore
Create a new src directory, this directory will be the main directory of the project.
mkdir src
touch App.tsx
Add some content to App.tsx
. We’re expecting to print out the text Hello from ReactJS
when user access our ReactJS app.
// src/App.tsx
import React from 'react';
const App: React.FC = () => {
return (
<h3>Hello from ReactJS</h3>
)
}
export default App;
Next we need an entrypoint where we’re gonna mount our app to the DOM, our app will be mounted into a <div id="root"></div>
. Move to next section to see how to add this element to HTML page.
touch index.tsx
// src/index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Configure webpack and Typescript
We need to add wepack as source bundler, we need to add weback config file as following.
// webpack.config.ts
const path = require("path");
module.exports = {
output: {
path: path.resolve(__dirname, "build"),
filename: "bundle.js",
},
entry: {
index: path.join(__dirname, "src/index.tsx"),
},
resolve: {
extensions: [".ts", ".tsx", ".js"],
},
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
}
}
output
- indicates where to put the result after bundling.entry
- the entrypoint which webpack will come to here firstly to bundle code.resolve
- as we support Typescript, we make sure webpack understand what we expect to do when it seeimport App from './App'
.rules
- specfies which loader will handle file extension, we will use thets-loader
to bundlets
andtsx
file. Just add it to devDependencies:
yarn add -D ts-loader
The ts-loader
needs tsconfig.json
file to config the Typescript compiler.
// tsconfig.json
{
"compilerOptions": {
"noImplicitAny": true,
"module": "es6",
"target": "es5",
"jsx": "react",
"allowJs": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true
}
}
webpack-dev-server and html-webpack-plugin
yarn add -D webpack-dev-server html-webpack-plugin
We need a wepack-dev-server
to serve the request to our app, and inside the HTML file we need an ⚓ where our app will mount to.
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="ReactJS from scratch"
/>
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
As you can see, there is script
tag here to inject the bundled code here. And this is where html-webpack-plugin
saves us.
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
...
+ plugins: [
+ new HtmlWebpackPlugin({
+ hot: true,
+ template: "./public/index.html",
+ }),
+ ],
+ devServer: {
+ contentBase: path.join(__dirname, "build"),
+ compress: true,
+ port: 8080,
+ },
};
Final step
Just add some scripts to package.json
file to build and start webpack-dev-server
// package.json
{
"scripts": {
"build": "webpack --config ./webpack.config.ts",
"start": "webpack serve --env development --open"
}
}
Now, we just need to run yarn start
and access [http://localhost:8080](http://localhost:8080)
to see the result.
All code is available on Github repository.