Webpack and Babel — What are they, and how to use them with React

发布时间 2023-05-27 23:36:03作者: saaspeter

摘抄自:https://medium.com/@agzuniverse/webpack-and-babel-what-are-they-and-how-to-use-them-with-react-5807afc82ca8

Webpack and Babel — Tools we can’t code without

We’ll be configuring both of these for our React project, so first here’s a quick explanation what these tools are.

Webpack is a bundler that uses a dependency graph to bundle our code and assets (incuding static assets such as images) into a ‘bundle’ which we can then deploy.

Creating a huge monolithic JavaScript file is ugly and difficult to maintain, but multiple JavaScript files require multiple requests to fetch, and can add significant overhead. The solution is to write code splitting it into as many files as you need, and using require() (and as we’ll soon see, import ) statements to connect them together as we see fit. When we requiresomething from a file, that becomes a dependency of that file. All our interconnected files and assets form a dependency graph. Then we use a bundler to to parse through these files and connect them appropriately based on the require and import statements and perform some more optimizations on top of it to generate one (sometimes more than one) JavaScript files which we can then use.

Webpack can also load non-js files, such as static assets, JSON files, CSS and more.

Babel, on the other hand, is a JavaScript compiler, sort of. It doesn’t compile JavaScript the same way gcc compiles C++. Instead it compiles newer JavaScript into older JavaScript. Technically, it is a transpiler.

What this means you can write your JavaScript using the latest features the language has to offer and Babel will compile your code into JavaScript that will run without issues on most browsers, even if they don’t support the cutting edge standards. Specifically in the case of React, your code will be in JSX format, which of course is not a standard supported by browsers, and you’ll need Babel to compile it down to regular JavaScript.

Configuring a new React app with Babel and Webpack

You’ll need to have Node and NPM installed. These are the only requirements.

Create a new folder and run npm init -y in it to initialize a blank project. (npm asks you a few configuration questions if you don’t use the -y option, you can do that if you don’t want to change them in your package.json later.)

Now you’ll have a package.json file which looks like this:

{
  "name": "test-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

 

Now let’s install Webpack and Babel and add them as dependencies in package.json

npm i webpack webpack-cli webpack-dev-server --save-dev

This installs Webpack and the webpack-cli, which is a command line interface to use Webpack. webpack-dev-server is a simple server that we can use during development.

npm i @babel/core @babel/preset-env @babel/preset-react

This installs the core Babel package and two of Babel’s presets. Babel works by using ‘plugins’ to it’s core package to transform and compile the code you give it. preset-env is such a plugin that compiles down ES6+ (That is, versions of JavaScript that implement ECMAscript 2015 and newer standards) to ES5 standards-compatible JavaScript. If that didn’t make sense, know that it just makes your JavaScript work with browsers that don’t natively support these new features yet.

preset-react is similarly another plugin that allows Babel to recognize and compile React code.

Time to configure Webpack.

Create a new file called webpack.config.js and add the following:

 1 const path = require('path')
 2 
 3 module.exports = {
 4     "entry": "./src/index.js",
 5     "output": {
 6         path: path.resolve(__dirname, 'dist'),
 7         filename: "bundle.js"
 8     },
 9     module: {
10         rules: [
11             {
12                 test: /\.(js|jsx)$/,
13                 exclude: /node_modules/,
14                 use: "babel-loader"
15             },
16             {
17                 test: /\css$/,
18                 use: [
19                     {
20                         loader: "style-loader"
21                     },
22                     {
23                         loader: "css-loader"
24                     }
25                 ]
26             }
27         ]
28     }
29 }

 

Let’s go over what this does. Path is a handy module that comes with your Node installation that is used here to create an absolute path that is to be set as the output path for Webpack in line 6. entry is the file from which Webpack starts parsing your project. If you come from a background of C-like languages, think of it as the main() function for your code.

Under module , we specify some rules that should be used for different kind of files. Loaders are plugins for Webpack that are used for preprocessing files before they are bundled by webpack. For .js and .jsx files, we tell Webpack to use babel-loader which makes Webpack run these files through Babel before bundling them. For .css files we chain two loaders. style-loader allows us to import CSS into our JavaScript files, and css-loaderallows us to use @import and url() in our CSS code. I won’t be using CSS in this little sample project, but I would consider these loaders essential.

(Check out the full list of loaders here: https://webpack.js.org/loaders/. Webpack also has many more configuration options, including a no-configuration option that runs with all default configurations, even if there is no webpack.config.js file.)

In case you haven’t guessed it already, we have to install these loaders before they can actually work.

npm i babel-loader style-loader css-loader --save-dev

Now let’s create .babelrc , the configuration file for Babel. It’s nice and simple, with it’s purpose obvious — tell babel to use the plugins we installed earlier.

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

 

Now it’s time to install React and get to coding!

npm i react react-dom --save

Now let’s create a src folder and inside that, write all our actual code. An html file is must, followed by the index.js which we specified as the entry point for Webpack and an App.js which will be the actual starting point for our app, since index.js just renders the contents of your app into the HTML element you specify.

 1 <!DOCTYPE html>
 2 <html lang="en">
 3   <head>
 4     <meta charset="UTF-8" />
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge" />
 7     <title>React App</title>
 8   </head>
 9   <body>
10     <div id="root"></div>
11   </body>
12 </html>
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(<App />, document.getElementById('root'));
import React from 'react';

class App extends React.Component {
    render() {
        return (
            <div>Welcome to React!</div>
        );
    }
}

export default App;
 

Finally we have to install html-webpack-plugin and update our Webpack configuration to use it.

npm i html-webpack-plugin --save-dev
 1 const path = require('path')
 2 const HtmlWebpackPlugin = require('html-webpack-plugin')
 3 
 4 module.exports = {
 5     "entry": "./src/index.js",
 6     "output": {
 7         path: path.resolve(__dirname, 'dist'),
 8         filename: "bundle.js"
 9     },
10     module: {
11         rules: [
12             {
13                 test: /\.(js|jsx)$/,
14                 exclude: /node_modules/,
15                 use: "babel-loader"
16             },
17             {
18                 test: /\css$/,
19                 use: [
20                     {
21                         loader: "style-loader"
22                     },
23                     {
24                         loader: "css-loader"
25                     }
26                 ]
27             }
28         ]
29     },
30     plugins: [
31         new HtmlWebpackPlugin({
32             template: "./src/index.html"
33         })
34     ]
35 }

 

This plugin automatically creates an HTML file that serves the JavaScript bundles created by Webpack.

As a last step, we modify the Scripts inside our package.json to include:

"start": "webpack-dev-server --mode development --open --hot"

This allows us to run npm start to start the Webpack development server. The open and hot options opens our React app in a browser once it’s ready and enables hot reloading, respectively.

That should give us our final working React app.

Alternatives to Webpack

While Babel is pretty much the de-facto tool used for JavaScript compilation, Webpack does have some alternatives, such as Parcel(https://parceljs.org/).

Even npm has alternatives, such as yarn (https://yarnpkg.com/lang/en/), which is the what I prefer over npm.

Each of them have their pros, cons and differences, and it’s up to you to explore them and choose the right tool for the job.

Conclusion

If you are a beginner it might be worth it to just use create-react-app or a similar tool for whatever framework/library you are working with to skip the (admittedly) tedious initial configuration, but if you are building a project that you plan to take to completion, I feel it is important to have control over every aspect of it to avoid bloat and to allow for micromanagement, and in these cases knowing your node_modules can be a good thing.

All files discussed in this article can be found here: https://github.com/agzuniverse/webpack-babel-react