A ReactJS használata a Webpack 4, a Babel 7 és az Anyagtervezéssel

Az elmúlt egy évben a React-tel dolgoztam együtt a Creative Tim-nél. A create-reagál-alkalmazást néhány szép termék fejlesztésére használtam. Nagyon sok ügyfél kérdezte, hogyan lehet valaki migrálni a Webpack terméksablonjainkat.

Tehát számos kérés után elkészítettük ezt a kis oktatóanyagot arról, hogy miként kezdhetjük el a React használatát a Webpack 4 és a Babel 7 használatával. Az oktatóanyag végén bemutatom nektek, hogyan adhatjuk hozzá a Material Dashboard React programot az újonnan létrehozott alkalmazást.

Mielőtt belekezdenénk, kérjük, győződjön meg arról, hogy az npm és a Nodejs legújabb verzióit globálisan telepítette a gépére. A bejegyzés írásakor a legújabb verziók 6.4.1 voltak az npm-re és 8.12.0 (lts) a Nodejs-re a gépemen.

Új projektmappa létrehozása a package.json használatával

Először hozzunk létre egy új mappát az új alkalmazáshoz, és írjuk be:

mkdir react-webpack-babel-tutorialcd react-webpack-babel-tutorial

Most, hogy létrehoztuk a mappát , amelyben fejleszteni fogjuk az alkalmazást , hozzá kell adnunk egy package.json fájlt. Ezt kétféleképpen tehetjük meg, és közülük válasszon egyet:

  1. csak konfigurálás nélkül hozza létre a package.json fájlt:
npm init -y

Amint láthatja, a package.json fájl létrejött, benne néhány alapvető információval.

2. hozza létre a package.json fájlt néhány további konfigurációs beállítással

npm init

Hozzáadtam néhány dolgot az újonnan létrehozott package.json fájlunkhoz , például néhány jó kulcsszót , egy repót és így tovább ...

Ezután adjunk hozzá egy index.html és index.js fájlt az új projekt mappánkhoz, egy src mappába.

  1. Linux / MacOS parancsok
mkdir srctouch src/index.htmltouch src/index.js

2. Windows parancsok

mkdir srcecho "" > src\index.htmlecho "" > src\index.js

Ezután tegyük fel az index.html fájlba a következő sablont .

     React Tutorial    You need to enable JavaScript to run this app. 

Tegyünk fel valamit az index.js-be, csak azért, hogy valami kirakat legyen, amit egy kicsit lejjebb fogunk látni.

(function () { console.log("hey mister");}());

És ez az, amit eddig megszereztünk:

Webpack hozzáadása a projekthez

Kezdjük hozzá az összes szükséges Webpack csomagot. DevDependency- ként telepítjük őket, mivel csak fejlesztési módban fogják használni őket.

npm install --save-dev webpack webpack-cli webpack-dev-server
  • webpack

    - használt új alkalmazásunk konfigurálásához

    - e bejegyzés idején a verzió 4.19.0 volt

  • webpack-cli

    - használatos, hogy a Webpack-ot a parancssorban tudjuk használni

    - e bejegyzés idején a verzió 3.1.0 volt

  • webpack-dev-server

    - arra használják, hogy amikor módosítunk egy fájlt az új alkalmazásunkban, akkor nem kell frissítenünk az oldalt. Automatikusan frissíti a böngésző oldalát, valahányszor fájlt cserélünk az alkalmazásunkban

    - ahogy a neve is mondja, ez egy olyan kiszolgáló, amely megállás nélkül működik

    - e bejegyzés idején a verzió 3.1.8 volt

Ha megnézzük a package.json fájlt, látni fogjuk, hogy ezt a három csomagot hozzáadták ehhez a fájlhoz:

"devDependencies": { "webpack": "^4.19.0", "webpack-cli": "^3.1.0", "webpack-dev-server": "^3.1.8"}

Folytatom, és minden verzióból törlöm a ^ (caret) szót. Ez azért van, mert nem tudom megmondani, hogy ezeknek a bővítményeknek a következő verziója továbbra is működni fog-e azzal, amit építek. Úgy gondolom, hogy ennek józan észnek kell lennie. Új alkalmazás létrehozásakor használja az elérhető verziókat, majd tegyen néhány frissítést az újabb verziókra. Előfordulhat, hogy nem tudja, mi új verzió törik el az alkalmazásában.

Amint látni fogja, ezeknek a bővítményeknek a telepítése néhány változtatást hozott a projekt mappánkban. Hozzáadta a node_modules mappát és a package-lock.json fájlt .

Most, mi kell hozzá egy új fájlt a projekt, a konfigurációs fájlt Webpack nevű webpack.config.js :

  1. Linux / MacOS parancs
touch webpack.config.js

2. Windows parancs

echo "" > webpack.config.js

Vagy egyszerűen létrehozhatja manuálisan az új fájlt, ha nem akarja használni a parancssort.

Mielőtt folytatnánk a Webpack konfigurációs fájlt, kezdjünk el telepíteni néhány dolgot, amelyekre szükségünk lesz az alkalmazásunkban.

Először a Webpack konfigurációs fájlban található néhány útvonallal fogunk dolgozni. Telepítsük a projektünkbe az elérési utat devDependency-ként.

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.

  1. 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:

  1. 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] [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/