如何使用Webpack4和Babel7设置React

来自菜鸟教程
跳转至:导航、​搜索

介绍

学习 React 的一种常用方法是使用 create-react-app,这是一种引导任何 React 项目的轻量级方法。 但为了达到特定目的,有时需要从头开始配置您的应用程序。 在本教程中,我们将使用 Webpack 和 Babel 设置 React。

第 1 步 — 设置项目

在开始之前,请确保在您的机器上安装了编辑器和终端。 此外,您还需要安装了带有 npm Node.js 版本。 在继续阅读之前,请确保已完成所有设置。

在我们开始编写任何代码之前,让我们创建一个新目录来存放我们的项目。 在您计算机上的任何位置,在终端中运行以下命令:

mkdir webpack-babel-react-starter
cd webpack-babel-react-starter

我们需要使用 package.json 文件初始化我们的项目,因为我们将安装一些对设置至关重要的包。 运行以下命令:

yarn init -y

注意: 在本教程中,我们将使用 yarn 作为我们的包管理器。 如果您使用的是 npm,请确保运行相应的命令。


第 2 步 — 设置 Webpack

Webpack 是最流行的 Web 开发打包工具之一。 它在处理您的应用程序时在内部构建 依赖关系图 。 该图映射了您的项目需要的每个模块并生成一个或多个捆绑包。 从 4.0.0 版本开始,webpack 不需要配置文件来打包你的项目; 然而,它是可配置的,以更好地满足您的需求。

让我们通过运行来安装它:

yarn add webpack --dev

我们还需要安装 webpack CLI:

yarn add webpack-cli --dev

安装这两个包后,您会注意到我们的项目中新增了一个,即我们的 package.json 文件中的 node_modulesdevDependencies 部分。

接下来要做的是将刚刚安装的 webpack 添加到 package.json 文件中。

"scripts": {
  "build": "webpack --mode production"
}

此时您不需要配置文件即可开始使用。

第 3 步 - 设置 Babel

现代 JavaScript 是用 ES6 或 ES7 编写的,但并不是每个浏览器都能理解这一点。 这里需要 babel 为我们做重光照。 Babel 是一个工具链,主要用于将 ECMAScript 2015+ 代码转换为当前和旧版浏览器或环境中向后兼容的 JavaScript 版本。 查看 Babel 文档 了解更多关于他们可以为你做什么的信息。

React 组件大多是用 ES6 编写的,带有导入、类和其他 ES6+ 特性的概念,这些都是旧版浏览器无法理解的。 Webpack 本身不知道如何将 ES6 代码转换或转译为 ES5 代码。 但它确实有 loader 的概念:webpack loader 接受类似于输入的东西并产生其他东西作为输出。

对于我们的设置,我们将使用 babel-loader,它是一个 webpack 加载器,它将为我们转译我们的 ES6 代码。 在我们开始使用 babel-loader 之前,我们需要安装一些包并设置 babel 预设 env,它将针对我们想要转译的特定 JavaScript 版本。

让我们安装所有依赖项:

yarn add @babel/core @babel/preset-env @babel/preset-react babel-loader --dev

我们还需要设置我们的 Babel 配置文件,在根目录中创建一个名为 .babelrc 的新文件,并将以下配置写入其中:

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

这种配置将确保 Babel 将我们的 React 代码,即 JSX 和我们必须的任何其他 ES6+ 代码转换为 ES5 代码。

在根目录下创建一个webpack.config.js文件,并为其编写如下配置:

module.exports = {
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  }
}

对于每个扩展名为 .js.jsx 的文件,不包括 node_modules 文件夹及其内容,Webpack 使用 babel-loader 将 ES6 代码转译为 ES5。

完成后,让我们开始编写我们的 React 组件。

第 4 步 — 设置 React

我们将创建一个渲染文本和按钮的 React 组件,但是为了使用 React,我们需要安装一些依赖项: reactreact-dom

yarn add react react-dom

安装后,在根目录中创建一个新文件夹。 我们称它为 src,并在其中创建一个 index.js 文件。

index.js文件中,编写如下代码:

import React from "react";
import ReactDOM from "react-dom";

const Index = () => {
  return (
    <div className="full-screen">
      <div>
        <h1>
          React Page {" "}
        </h1>
        <br />
        <a
          className="button-line"
          href="https://github.com/deityhub"
          target="_blank"
        >
          Know more
        </a>
      </div>
    </div>
  );
};

export default Index;

是时候测试一下了。 再次打开终端并运行:

yarn run build

你会看到一个由 Webpack 为我们创建的 dist 文件夹,里面有一个 index.js 文件,我们在其中有一个 ES5 代码的缩小版本。 在 package.json 中的构建脚本中,我们在 webpack 命令之后指定了 --mode production 标志; 这使得 Webpack 生成我们的 ES5 代码的缩小版本。 要查看转译代码的可读格式,您可以将 --mode production--mode development 交换。

输出显示我们的代码有效,但我们希望我们的转译代码在浏览器中可见。 为此,让我们设置 HTML 和 CSS (SCSS) 以使用 Webpack。

第 5 步 — 将 React 组件连接到 DOM

我们需要设置一个 HTML 文件,以便我们的 React 组件可以在 DOM 上呈现。 为此,我们需要安装包 html-webpack-plugin

yarn add html-webpack-plugin --dev

webpack.config.js 文件调整为如下所示:

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: "bundle.js"
  },
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: path.join(__dirname, "src", "index.html")
    })
  ]
};

我们正在调整输入和输出,因此我们可以更好地控制文件的命名和目标。

接下来是在 src 文件夹中创建一个 HTML 文件; 我们称它为 index.html ,然后添加以下代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>React, Webpack, Babel Starter Pack</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <noscript> You need to enable JavaScript to run this app. </noscript>
    <!-- your react app will render here -->
    <div id="app"></div>
  </body>
</html>

由于我们在 src 目录中,让我们对我们的 React 组件进行一些调整。 首先,新建一个文件夹components,然后在这个文件夹中添加两个文件app.jsapp.scss。 对我们的代码进行以下调整。

./src/index.js 中:

import React from "react";
import ReactDOM from "react-dom";
import App from "./components/app";

ReactDOM.render(<App />, document.getElementById("app"));

./src/components/app.js

import React from "react";
import "./app.scss";

const App = () => {
  return (
    <div className="full-screen">
      <div>
        <h1>
          React Page {" "}
        </h1>
        <br />
        <a
          className="button-line"
          href="https://github.com/deityhub"
          target="_blank"
        >
          Know more now
        </a>
      </div>
    </div>
  );
};

export default App;

./src/components/app.scss 中:

body {
  background: linear-gradient(253deg, #0cc898, #1797d2, #864fe1);
  background-size: 300% 300%;
  -webkit-animation: Background 25s ease infinite;
  -moz-animation: Background 25s ease infinite;
  animation: Background 25s ease infinite;
}

.full-screen {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
//you need to setup file-loader in webpack before you can use images
  background: url("../../assests/image/background.png");
  background-size: cover;
  background-position: center;
  width: 100%;
  height: 100%;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-direction: column;
  //_ works with row or column_

  flex-direction: column;
  -webkit-align-items: center;
  align-items: center;
  -webkit-justify-content: center;
  justify-content: center;
  text-align: center;
}

h1 {
  color: #fff;
  font-family: "Open Sans", sans-serif;
  font-weight: 800;
  font-size: 4em;
  letter-spacing: -2px;
  text-align: center;
  text-shadow: 1px 2px 1px rgba(0, 0, 0, 0.6);

  &:after {
    display: block;
    color: #fff;
    letter-spacing: 1px;
    font-family: "Poiret One", sans-serif;
    content: "React project powered by webpack and babel with support for sass";
    font-size: 0.4em;
    text-align: center;
  }
}

.button-line {
  font-family: "Open Sans", sans-serif;
  text-transform: uppercase;
  letter-spacing: 2px;
  background: transparent;
  border: 1px solid #fff;
  color: #fff;
  text-align: center;
  font-size: 1.4em;
  opacity: 0.8;
  padding: 20px 40px;
  text-decoration: none;
  transition: all 0.5s ease;
  margin: 0 auto;
  display: block;

  &:hover {
    opacity: 1;
    background-color: #fff;
    color: grey;
  }
}

@-webkit-keyframes Background {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}

@-moz-keyframes Background {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}

@keyframes Background {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}

除了将在 DOM 中呈现的 HTML 和 React 组件之外,我们还将添加一些样式。 在我们运行我们的代码来测试它之前,我们需要配置我们的 Webpack,以便它知道如何处理通过它传递的任何 .css.scss 文件。

yarn add css-loader sass-loader mini-css-extract-plugin node-sass --dev

Webpack 使用此处安装的 sass-loader 将我们的 .scss 转换为浏览器可以理解的 .css 文件,并在后台使用 node-sass为达到这个。 然后 mini-css-extract-plugin 将我们所有的 CSS 文件抽象成一个 CSS 文件,而不是 Webpack 提供的正常行为,即将你的 CSS 文件与最终的 .js 输出文件捆绑在一起,然后注入运行代码时将 CSS 放入呈现的 HTML 输出中。

打开你的 Webpack 配置文件并调整你的代码看起来像这样:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  entry: path.join(__dirname, "src", "index.js"),
  output: {
    path: path.join(__dirname, "build"),
    filename: "bundle.js"
  },
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /.(css|scss)$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: path.join(__dirname, "src", "index.html")
    }),
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[id].css"
    })
  ]
};

注意: 加载器在 Webpack 配置文件中的顺序很重要,因为 Webpack 从右到左处理加载器。 例如,对 CSS 文件使用测试将首先运行 sass-loader,然后是 css-loader,最后是 MiniCssExtractPlugin


现在让我们安装 webpack 开发服务器。 这将为我们创建一个开发服务器,并监视我们的文件在开发过程中是否有任何更改。

yarn add webpack-dev-server --dev

然后打开您的 package.json 文件并在您的脚本标签中进行以下调整:

"scripts": {
    "start": "webpack --mode development",
    "dev": "webpack-dev-server --mode development --open",
    "build": "webpack --mode production"
  }

让我们通过运行 yarn run dev 来测试我们的代码。

您将在浏览器中看到类似这样的内容:

第 6 步 — 扩展功能

现在,让我们向这个项目添加另外两个特性,以演示在处理比这更高级的 React 项目时,您可以扩展或添加更多特性。

打开您的终端并安装这些软件包:

yarn add file-loader @babel/plugin-proposal-class-properties --dev

file-loader 将处理我们想要导入图像或 SVG 的所有场景,而 @babel/plugin-proposal-class-properties 将处理 React 类组件和静态类属性。

webpack.config.js 中将其调整为如下所示:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  entry: path.join(__dirname, "src", "index.js"),
  output: {
    path: path.join(__dirname, "build"),
    filename: "bundle.js"
  },
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /.(css|scss)$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
      },
      {
        test: /.(jpg|jpeg|png|gif|mp3|svg)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "[path][name]-[hash:8].[ext]"
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: path.join(__dirname, "src", "index.html")
    }),
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[id].css"
    })
  ]
};

.babelrc 文件中,也将其调整为如下所示:

{
  "presets": ["@babel/env", "@babel/react"],
  "plugins": ["@babel/plugin-proposal-class-properties"]
}

最后,运行 yarn run dev 以确保一切正常。

结论

以此作为 React 应用程序的基础,您可以扩展配置并从中构建一些东西。 如果遇到困难,请查看 GitHub 链接 以获取完整代码。