Usually we use the command npx create-react-app my-app
to create a React project, this command creates a project with a defined structure and is not suitable to existing projects that have their own project folder structure. In the case you want to integrate React into a existing project or you want to have your own project folder structure you can setup React with webpack to have this flexibility.
This post will be about setting up a React project using webpack and babel by creating as an example a html file with a button and some text using React.
We are going to go step by step but the final file structure should look like this:
| - .babelrc
| - index.html
| - dist
| | - index.js
| | - index.js.map
| - js
| | - text.jsx
| | - button.jsx
| | - index.js
| - node_modules
| - webpack.config.js
| - package-lock.json
| - package.json
Start by creating a project:
npm init
npm install --save-dev webpack webpack-cli
Webpack will use babel to process javascript and React code .jsx
.
npm install --save-dev babel babel-loader @babel/preset-env @babel/preset-react
.babelrc
with the following contents:{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
install react
and react-dom
: npm install react react-dom
create a file called webpack.config.js
with the following content:
const path = require('path');
const webpack = require("webpack");
module.exports = {
mode: 'development',
entry: {
'index':'./js/index.js',
},
module: {
rules: [{
test: /\.(jsx)$/,
exclude: path.resolve(__dirname, "node_modules"),
use: ['babel-loader']
}]
},
output: {
libraryTarget: "umd",
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
resolve: {
extensions: ['.js', '.jsx'],
},
devtool: 'source-map',
externalsPresets: {
node: true,
},
};
js
for the javascript filesdist
for the build filesNow lets start creating the html and javascript files, as an example lets create a button and a paragrahp in react.
js/button.jsx
:import React from 'react';
const button = (props) => {
return(
<button onClick={()=>{alert("button clicked!")}}>test</button>
)
}
export default button
js/text.jsx
with the content:import React from 'react';
const text = (props) => {
return(
<p>Some text</p>
)
}
export default text
js/index.js
:import ReactDOM from 'react-dom'
import text from './text'
import button from './button'
ReactDOM.render(button(), document.querySelector("#button"))
ReactDOM.render(text(), document.querySelector("#text"))
index.html
:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="button"></div>
<div id="text"></div>
<script src="/dist/index.js"></script>
</body>
</html>
We need now create the npm scripts to build the javascript files. Lets
add the file package.json
in the script
section the following entries:
"scripts": {
"webpack": "webpack --mode=production",
"webpack-watch": "webpack -w"
}
The final package.json
should look similar to this:
{
"name": "tmp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"webpack": "webpack --mode=production",
"webpack-watch": "webpack -w"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/preset-env": "^7.16.4",
"@babel/preset-react": "^7.16.0",
"babel": "^6.23.0",
"babel-loader": "^8.2.3",
"webpack": "^5.64.4",
"webpack-cli": "^4.9.1"
},
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
}
}
npm run webpack-watch
to build the javascript files, the javascript
file to be included on the html should be now in dist/index.js
Now if you serve the files you should see a button and some text in the browser.
You can serve the files with the command python3 -m http.server
or with
php -S 127.0.0.1:8000