How to create react apps from scratch without CRA (Set up Webpack4 for a React Project)
Webpack is a bundler. A bundler combines your code and it’s dependencies and puts them together in a file. This file is easier to deploy.
To fully understand this post, you should understand a bit of javascript, react/learning react. A general overview should be fine.
Install react and react dom
npm install react
Install webpack, webpack-dev-server and webpack-cli
npm i --save-dev webpack webpack-dev-server webpack-cli
Install @babel/core, babel-loader, @babel/preset-env, @babel/preset-react, html-webpack-plugin. html-webpack-plugin is a webpack plugin that makes it easy to create HTML files that serve webpack bundles.
npm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react html-webpack-plugin
Create a webpack.config.js file in the root directory to configure webpack.
In webpack.config.js require the path module and the html-webpack-plugin installed.
const path = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')
Specify an entry for your project in webpack.config.js
module.exports = {
entry: './src/index.js'}
To the webpack.config.js specify the output path
output: { path: path.join(__dirname, '/dist'), filename: 'bundlefile.js'}
So the file looks like this at this point
const path = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = { entry: './src/index.js', output: { path: path.join(__dirname, '/dist'), filename: 'bundlefile.js' },}
Specify the test files and files to exclude.
module: { rules: [ { test: /\.js$/, exclude: /node_modules/, } ]},
The $ sign behind the test files script represents a regex symbol for end of string or end of line.
Create the src directory and create the index.js and index.html files inside the src directory.
In the index.html file, create a template html file and in its body, create a div with an id as ‘App’
<!DOCTYPE html><html><head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Send it react</title> <meta name="viewport" content="width=device-width, initial- scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <script src="main.js"></script></head><body> <div id="App"></div></body></html>
In the index.js file, import react and react-dom and the component to render. In our case, App. The index.js is an entry point for the project. React DOM renders components on the DOM so in the code below, the component ‘App’ is rendered. If App is a stateful component, it returns a reference to the component. If it is a stateless component, it returns null.
import React from 'react'import ReactDOM from 'react-dom'import App from './js/components/App.js'
ReactDOM.render(<App/> , document.getElementById('app'))
Specify the loader as babel-loader in the webpack.config.js
module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }]},
Add all webpack plugins you would need. The plugin needed at this point is the html-webpack-plugin to bundle the index.html file we created.
plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' })]
So the entire webpack.config.js looks like this:
const path = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = { entry: './src/index.js', output: { path: path.join(__dirname, '/dist'), filename: 'bundlefile.js' }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ]}
Configure the application to use babel by creating a .babelrc file in the root directory of the project.
The .babelrc file is an object. In it, set the presets to work based on the environment of the application( test, development, production).
{
"presets": [
"@babel/preset-env",
"@babel/react"
]
}
Create App.js in src/js/components.
import React from 'react'const App = () => { return( <div> <h1>Hello React</h1> </div> )}export default App;
In package.json, write the start script. in my case, this is what my script looks like in package.json:
"dev": "webpack-dev-server --mode development --open",
If you are comfortable with start, you can also use it, there are no rules.
"start": "webpack-dev-server --mode development --open",
To run the project, depending on the name you have used in your script , run the app.
npm run dev
or
npm run start