
Posljednjih godinu dana i neke, radim s Reactom u Creative Timu. Koristim aplikaciju create-response-za razvoj nekih lijepih proizvoda. Puno je klijenata pitalo kako netko može migrirati naše predloške proizvoda na Webpack.
Dakle, nakon niza zahtjeva, stvorili smo ovaj mali vodič o tome kako početi koristiti React s Webpack 4 i Babel 7. Na kraju tutorijala, pokazat ću vam kako dodati dodavanje materijalne nadzorne ploče React na novo kreirana aplikacija.
Prije nego što započnemo, provjerite imate li na svom računalu najnovije verzije npm i Nodejs globalno instalirane. U vrijeme pisanja ovog posta, najnovije verzije bile su 6.4.1 za npm i 8.12.0 (lts) za Nodejs na mom računalu.
Stvaranje nove mape projekta s package.json
Prvo najprije stvorimo novu mapu za našu novu aplikaciju i unesite je:
mkdir react-webpack-babel-tutorialcd react-webpack-babel-tutorial
Sad kad smo stvorili mapu u kojoj ćemo razvijati aplikaciju , u nju moramo dodati datoteku package.json . To možemo učiniti na dva načina, a vi biste trebali odabrati jedan od njih:
- samo stvorite datoteku package.json bez ikakve druge konfiguracije:
npm init -y
Kao što vidite, datoteka package.json stvorena je s vrlo osnovnim informacijama.


2. stvorite datoteku package.json s nekim dodatnim konfiguracijskim postavkama
npm init
Dodao sam neke stvari u našu novostvorenu datoteku package.json , kao što su neke lijepe ključne riječi , repo i tako dalje ...


Nakon toga, dodajmo datoteke index.html i index.js u našu novu mapu projekta, unutar mape src .
- Linux / MacOS naredbe
mkdir srctouch src/index.htmltouch src/index.js
2. Windows naredbe
mkdir srcecho "" > src\index.htmlecho "" > src\index.js
Nakon toga, dodajmo sljedeći predložak unutar index.html.
React Tutorial You need to enable JavaScript to run this app.
Dodajmo nešto unutar index.js samo radi neke vitrine koju ćemo vidjeti malo niže.
(function () { console.log("hey mister");}());
I ovo je što smo do sada dobili:

Dodavanje Webpacka u projekt
Počnimo dodavati sve Webpack pakete koji će nam trebati. Instalirat ćemo ih kao ovisnosti o razvoju jer će se koristiti samo u razvojnom načinu.
npm install --save-dev webpack webpack-cli webpack-dev-server
- webpack
- koristi se za konfiguriranje naše nove aplikacije
- u vrijeme ovog posta verzija je bila 4.19.0
- webpack-cli
- koristi se tako da možemo koristiti Webpack u naredbenom retku
- u vrijeme ovog posta verzija je bila 3.1.0
- webpack-dev-poslužitelj
- koristi se tako da kada napravimo promjenu datoteke u našoj novoj aplikaciji, nećemo trebati osvježavati stranicu. Automatski osvježava stranicu preglednika svaki put kad promijenimo datoteku u našoj aplikaciji
- kao što mu i samo ime kaže, to je poslužitelj koji radi bez prestanka
- u vrijeme ovog posta verzija je bila 3.1.8

Ako zavirimo u datoteku package.json , vidjet ćemo da su ova tri paketa dodana u ovu datoteku ovako:
"devDependencies": { "webpack": "^4.19.0", "webpack-cli": "^3.1.0", "webpack-dev-server": "^3.1.8"}
Idem naprijed i iz svake verzije obrišem ^ (znak). To je zato što ne mogu reći hoće li sljedeća verzija ovih dodataka i dalje raditi s onim što gradim. Mislim da je to nešto što bi trebalo biti zdrav razum. Prilikom izrade nove aplikacije upotrijebite dostupne verzije, a zatim, možda napravite neka ažuriranja novijih verzija. Možda ne znate što će nova verzija pokvariti vašu aplikaciju.
Kao što ćete vidjeti, instalacija ovih dodataka unijela je neke promjene u mapu našeg projekta. Dodao je mapu node_modules i package-lock.json u nju.

Sada u naš projekt moramo dodati novu datoteku, konfiguracijsku datoteku za Webpack nazvanu webpack.config.js :
- Naredba Linux / MacOS
touch webpack.config.js
2. Windows naredba
echo "" > webpack.config.js
Ili možete jednostavno ručno stvoriti novu datoteku ako ne želite koristiti naredbeni redak.
Prije nego što krenemo i počnemo se zezati s konfiguracijskom datotekom Webpack , prvo instalirajmo neke stvari koje će nam trebati u našu aplikaciju.
Prvo ćemo raditi s nekim stazama unutar konfiguracijske datoteke Webpack. Instalirajmo put u naš projekt kao devDependency.
npm install --save-dev path
Also, since we don’t want to manually inject the index.js file inside the HTML one, we are going to need a plugin called html-webpack-plugin. This plugin will inject the index.js inside the HTML file without any manual operation.
npm install --save-dev html-webpack-plugin
Once again, I am going to edit my package.json file and delete all the ^ (caret) occurrences from it.
One more edit that we are going to make to our package.json is to add some new scripts inside the scripts object, after the test script (See the second example below).
"webpack": "webpack","start": "webpack-dev-server --open"
This is what your package.json should look like at this point:
{ "name": "react-webpack-babel-tutorial", "version": "1.0.0", "description": "This is a Tutorial to showcase the usage of React with Webpack and Babel", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "webpack": "webpack", "start": "webpack-dev-server --open" }, "repository": { "type": "git", "url": "git+//github.com/creativetimofficial/react-webpack-babel-tutorial.git" }, "keywords": [ "react", "webpack", "babel", "creative-tim", "material-design" ], "author": "Creative Tim (//www.creative-tim.com/)", "license": "MIT", "bugs": { "url": "//github.com/creativetimofficial/react-webpack-babel-tutorial/issues" }, "homepage": "//github.com/creativetimofficial/react-webpack-babel-tutorial#readme", "devDependencies": { "html-webpack-plugin": "3.2.0", "path": "0.12.7", "webpack": "4.19.0", "webpack-cli": "3.1.0", "webpack-dev-server": "3.1.8" }}
Let’s go ahead and run these commands one by one and see what happens.
npm run webpack
Webpack will automatically take the src/index.js file, compile it, and output it inside dist/main.js and will minify that code. This is because we haven’t yet configured the Webpack config file. Also, since we haven’t configured the file, we are going to have some warnings in our console.



If we run the other command
npm start
webpack-dev-server will automatically start a server and open the default browser with this server. But once again, since we do not have our webpack.config.js file configured, the output will not be the expected one.


If you want to stop the server, just press at the same time the CTRL + C keys while in the command line.
Let’s add the following template inside our Webpack config file:
const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = { entry: path.join(__dirname,'src','index.js'), output: { path: path.join(__dirname,'build'), filename: 'index.bundle.js' }, mode: process.env.NODE_ENV || 'development', resolve: { modules: [path.resolve(__dirname, 'src'), 'node_modules'] }, devServer: { contentBase: path.join(__dirname,'src') }, plugins: [ new HtmlWebpackPlugin({ template: path.join(__dirname,'src','index.html') }) ]};
- entry and output
— these are used to tell our server what has to be compiled and from where (entry: path.join(__dirname,’src’,’index.js’),). It also tells where to put the outputted compiled version (output — the folder and the filename)
- mode
— this is the mode of our output. We are setting it to ‘development’. If in the scripts we specify the NODE_ENV variable, it will take that one instead. See the below example on how to use NODE_ENV (note that the below changes will not be made inside the package.json file in this tutorial, it is just an example for you to see how it works)
"webpack": "NODE_ENV=production webpack",
- resolve
— this is used so that we can import anything from src folder in relative paths instead of absolute ones. It is the same for the node_modules. We can import anything from node_modules directly without absolute paths
- devServer
— this tells the webpack-dev-server what files are needed to be served. Everything from our src folder needs to be served (outputted) in the browser
- plugins
— here we set what plugins we need in our app. As of this moment we only need the html-webpack-plugin which tells the server that the index.bundle.js should be injected (or added if you will) to our index.html file
If we now run the earlier commands we will see some differences.
npm run webpack



We’ve changed where the output should be (from dist folder to build folder). By changing the mode of Webpack, now the code has a different look. It is not minified as the last time with no config.
npm start



The webpack-dev-server took everything from the src folder and outputted it to our browser.
We are on the right path, but we’ve only added Webpack to our project. Where are React and Babel? Well, that is what we are going to do next.
React, Babel and some nice loaders for styles
Add React and ReactDOM to our project as normal dependencies.
npm install --save react react-dom
At this moment in our development, if we were to add React code inside our JS file, Webpack will give us an error. It doesn’t know how to compile React inside the bundle.js file.
Let’s modify the index.js file as follows:
import React from "react";import ReactDOM from "react-dom";let HelloWorld = () => { return Hello there World!
}ReactDOM.render( , document.getElementById("root"));
And after that let’s start the server again.
npm start
And this is the error:


So this is where Babel comes to our aid. Babel will tell Webpack how to compile our React code.
Let’s go ahead and add a bunch of Babel packages to our app as devDependencies.
npm install --save-dev @babel/core @babel/node @babel/preset-env @babel/preset-react babel-loader
- @babel/core
— this is used to compile ES6 and above into ES5
- @babel/node
— this is used so that we can import our plugins and packages inside the webpack.config.js rather than require them (it’s just something that I like, and maybe you’ll like it too)
- @babel/preset-env
— this will determinate which transformations or plugins to use and polyfills (i.e it provides modern functionality on older browsers that do not natively support it) based on the browser matrix you want to support
- @babel/preset-react
— this is going to compile the React code into ES5 code
- babel-loader
— this is a Webpack helper that transforms your JavaScript dependencies with Babel (i.e. will transform the import statements into require ones)
Since you are probably going to need to add some styles to your project (I know that I need them), we are going to add a loader that will let us import and use CSS files and SCSS files.
npm install --save-dev style-loader css-loader sass-loader node-sass
- style-loader
— this will add to the DOM the styles (will inject a
le> tag inside the HTML file) - css-loader
— will let us import CSS files into our project
- sass-loader
— will let us import SCSS files into our project
- node-sass
— will compile the SCSS files into normal CSS files
We are going to create a new SCSS file and add it to our folders.
- Linux/MacOS command
touch src/index.scss
2. Windows command
echo "" > src/index.scss
And also add some nice styles to it.
body { div#root{ background-color: #222; color: #8EE4AF; }}
And change our index.js by adding an import for the SCSS file.
import React from "react";import ReactDOM from "react-dom";
// this line is new// we now have some nice styles on our react appimport "index.scss";
let HelloWorld = () => { return Hello there World!
}
ReactDOM.render( , document.getElementById("root"));
Don’t forget to delete the carets (^) from package.json.
This is how your package.json should look like:
{ "name": "react-webpack-babel-tutorial", "version": "1.0.0", "description": "This is a Tutorial to showcase the usage of React with Webpack and Babel", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "webpack": "webpack", "start": "webpack-dev-server --open" }, "repository": { "type": "git", "url": "git+//github.com/creativetimofficial/react-webpack-babel-tutorial.git" }, "keywords": [ "react", "webpack", "babel", "creative-tim", "material-design" ], "author": "Creative Tim (//www.creative-tim.com/)", "license": "MIT", "bugs": { "url": "//github.com/creativetimofficial/react-webpack-babel-tutorial/issues" }, "homepage": "//github.com/creativetimofficial/react-webpack-babel-tutorial#readme", "devDependencies": { "@babel/core": "7.0.1", "@babel/node": "7.0.0", "@babel/preset-env": "7.0.0", "@babel/preset-react": "7.0.0", "babel-loader": "8.0.2", "css-loader": "1.0.0", "html-webpack-plugin": "3.2.0", "node-sass": "4.9.3", "path": "0.12.7", "sass-loader": "7.1.0", "style-loader": "0.23.0", "webpack": "4.19.0", "webpack-cli": "3.1.0", "webpack-dev-server": "3.1.8" }, "dependencies": { "react": "16.5.1", "react-dom": "16.5.1" }}
If we run any of the above commands again, the error will still persist. We haven’t yet told Webpack that it should use Babel and the style loaders to compile our React and SCSS code.
Next thing to do is add a configuration file for Babel. For this we need to create a file named .babelrc in which we will configure Babel.
I’ve heard that you can add the configuration for Babel directly in the webpack.config.js file. For this, you can take a look at the official babel-loader docs. As far as I am concerned, I think it’s best to have the Babel config in its own file. That way you do not overcrowd your Webpack config.
So, let’s run in the command line the following:
- Linux/MacOS command
touch .babelrc
2. Windows command
echo "" > .babelrc
And add the following code inside .babelrc so that babel-loader will know what to use to compile the code:
{ "presets": [ "@babel/env", "@babel/react" ]}
After these steps, we will need to add something to our project so we can import all sorts of files such as images. We will also need to add a plugin that will let us work with classes and much more. Let us add class properties in our classes. Basically, it will let us work with Object Oriented Programming — nice.
npm install --save-dev file-loader @babel/plugin-proposal-class-properties
Now that we have done this, we need to make some changes inside webpack.config.js so that Webpack will now use Babel. We’ll also configure Webpack to listen for style files and we are going to change the require statements to import ones.
So this being said, let’s change our webpack.config.js to the following (I’ve also added some comments, maybe they will help you):
// old// const path = require('path');// const HtmlWebpackPlugin = require('html-webpack-plugin');// newimport path from 'path';import HtmlWebpackPlugin from 'html-webpack-plugin';module.exports = { entry: path.join(__dirname,'src','index.js'), output: { path: path.join(__dirname,'build'), filename: 'index.bundle.js' }, mode: process.env.NODE_ENV || 'development', resolve: { modules: [path.resolve(__dirname, 'src'), 'node_modules'] }, devServer: { contentBase: path.join(__dirname,'src') }, module: { rules: [ // this is so that we can compile any React, // ES6 and above into normal ES5 syntax test: /\.(js, scss)$/, use: [ "style-loader", // creates style nodes from JS strings "css-loader", // translates CSS into CommonJS "sass-loader" // compiles Sass to CSS, using Node Sass by default ] , svg)$/, loaders: ['file-loader'] ] }, plugins: [ new HtmlWebpackPlugin({ template: path.join(__dirname,'src','index.html') }) ]};
There’s one more change we need to do to the package.json file. We need to tell our scripts that inside the config files of Webpack, we use import instead of require statements. Else it will give us an error that it doesn’t know what import stands for.
{ "name": "react-webpack-babel-tutorial", "version": "1.0.0", "description": "This is a Tutorial to showcase the usage of React with Webpack and Babel", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "webpack": "babel-node ./node_modules/webpack/bin/webpack", "start": "babel-node ./node_modules/webpack-dev-server/bin/webpack-dev-server --open" }, "repository": { "type": "git", "url": "git+//github.com/creativetimofficial/react-webpack-babel-tutorial.git" }, "keywords": [ "react", "webpack", "babel", "creative-tim", "material-design" ], "author": "Creative Tim (//www.creative-tim.com/)", "license": "MIT", "bugs": { "url": "//github.com/creativetimofficial/react-webpack-babel-tutorial/issues" }, "homepage": "//github.com/creativetimofficial/react-webpack-babel-tutorial#readme", "devDependencies": { "@babel/core": "7.0.1", "@babel/node": "7.0.0", "@babel/plugin-proposal-class-properties": "7.0.0", "@babel/preset-env": "7.0.0", "@babel/preset-react": "7.0.0", "babel-loader": "8.0.2", "css-loader": "1.0.0", "file-loader": "2.0.0", "html-webpack-plugin": "3.2.0", "node-sass": "4.9.3", "path": "0.12.7", "sass-loader": "7.1.0", "style-loader": "0.23.0", "webpack": "4.19.0", "webpack-cli": "3.1.0", "webpack-dev-server": "3.1.8" }, "dependencies": { "react": "16.5.1", "react-dom": "16.5.1" }}
Another thing that we will have to still add is the @babel/plugin-proposal-class-properties to the .babelrc file. Babel will know how to deal with class properties.
{ "presets": [ "@babel/env", "@babel/react" ], "plugins": [ "@babel/plugin-proposal-class-properties" ]}
Now we are done. We can run either one of the above commands and it should not give us any errors. Let’s see them in action.
npm run webpack

Original text

And now let’s see the main script of our app.
npm start


Add Material Design to our new React with Webpack and Babel project
As I’ve told you at the beginning of this post, we are not going to create from scratch styles for Material Design. That would require a lot of work. We don’t have time for that.
Instead, we are going to add a nice product that implements Google’s Material Design with some minor touches from the Creative Tim staff. We are going to add Material Dashboard React to it.

First things first, you need to get the product. Here are a few ways of getting the product:
- Clone the repo inside another folder:
git clone //github.com/creativetimofficial/material-dashboard-react.git
- Download from Github
- Download from Creative Tim
Ok, so now we have both projects — Material Dashboard React and our newly created one with Webpack and Babel — with React.

Now, we can’t simply copy the src folder from Material Dashboard React into our new project. That will give us a lot of errors. Such as errors for missing dependencies, module not found, you get the point, a lot of errors.
So, I suggest that we start with adding the dependencies from Material Dashboard React’s package.json to our package.json. We do not need all the dependencies from Material Dashboard React’s packages, since we have built our own server using Webpack. We have added other style loaders beyond what the product has.
So this being said, we need the following:
npm install --save @material-ui/[email protected] @material-ui/[email protected] @types/[email protected] @types/[email protected] [email protected] [email protected] [email protected] [email protected] react-google[email protected] [email protected] [email protected]
We are not going through all of them. They can be found on npmjs.com with all the details and their own documentation.
Once again, we go inside the package.json file and delete the carets (^) from the packages that we just installed.
Ok, we are almost done. We are going to copy all the contents of the src folder from Material Dashboard React inside our project’s src folder and override the index.js file. But keep it in the index.html file.


Now we need to add some styles and fonts cdns inside our index.html.
React Tutorial You need to enable JavaScript to run this app.
And we are almost there. We still have a small problem. When we refresh the page, we have an error Cannot GET /dashboard. If we navigate to another page we will get, for example, Cannot GET /user and so on. So basically, our routes do not work. We need to make some changes inside either src/index.js or inside our webpack.config.js.
I will choose the first option since it is pretty straightforward and easy to understand.
We navigate inside the new index.js and we change the history type. We put createHashHistory() instead of createBrowserHistory().
This will allow us to refresh the page without any other errors. Now we are done.
import React from "react";import ReactDOM from "react-dom";import { createHashHistory } from "history";import { Router, Route, Switch } from "react-router-dom";import "assets/css/material-dashboard-react.css?v=1.5.0";import indexRoutes from "routes/index.jsx";const hist = createHashHistory();ReactDOM.render( {indexRoutes.map((prop, key) => { return ; })} , document.getElementById("root"));
I really hope you’ve liked this tutorial and I am very keen on hearing your thoughts about it. Just give this thread a comment and I’ll be more than happy to reply.
Special thanks should also go to Linh Nguyen My for her tutorial which has given me some much needed understanding on Webpack.
Useful links:
- Get the code for this tutorial from Github
- Read more about ReactJS on their official website
- Read more about Webpack here
- Read more about Babel on this link here
- Read more about Material Design
- Check out our platform to see what we are doing and who we are
- Get Material Dashboard React from www.creative-tim.com or from Github
- Read more about Material-UI, the core of Material Dashboard React
Find me on:
- Email: [email protected]
- Facebook: //www.facebook.com/NazareEmanuel
- Instagram: //www.instagram.com/manu.nazare/