【譯】如何從頭開始搭建React,Webpack4,Babel7工程

EniviaQ發表於2019-03-03

這是一篇非常適合新手的教程。

How to set up React, webpack 4, and Babel (2018)

目錄:

  1. 你將會學習到的知識
  2. 建立專案
  3. 配置webpack
  4. 配置Babel
  5. 編寫React元件
  6. HTML webpack plugin
  7. webpack dev server
  8. 總結


你將會學習到的知識

  • 如何安裝及配置webpack
  • 如何安裝及配置Babel
  • 如何安裝React
  • 如何編寫React元件
  • 如何在HTML頁面中引入打包檔案
  • 如何安裝及配置webpack dev server


建立專案

首先,建立工程目錄:

mkdir webpack-react-tutorial && cd $_複製程式碼

建立工程的基礎目錄結構:

mkdir -p src複製程式碼

初始化專案:

npm init -y複製程式碼


配置webpack

webpack是一款非常強大的工具,學習webpack不僅可以用於搭建React專案,它適用於任何前端工程。

webpack提取原始的React元件,用於生成(幾乎)每個瀏覽器都能理解的JavaScript程式碼。

安裝webpack:

npm i webpack --save-dev複製程式碼

同時需要安裝webpack-cli:

npm i webpack-cli --save-dev複製程式碼

下一步,在package.json中新增webpack命令:

"scripts": {
    "build": "webpack --mode production"
}複製程式碼

現在你不需要為webpack定義配置檔案。

老版本的webpack不會自動查詢配置檔案,但從webpack4開始,不需要配置檔案就可以直接進行開發。

接下來我將安裝並配置Babel來編譯我們的程式碼。


配置Babel

React元件大多是由ES6語法編寫。ES6是對語法的一次很好的改進,但老版本瀏覽器往往不能解析新的ES6語法。有狀態的React元件被生命為class,因此,為了讓ES6在舊版瀏覽器中執行,我們需要進行某種轉換。我們把這種轉換成為編譯

webpack並不知道如何將ES6語法轉換為ES5,不過webpack可以使用loader來完成。即webpack載入器將一些東西作為輸入,並將其轉換為其他東西輸出。

webpack中的babel-loader便擔任著將ES6語法轉換為瀏覽器所能理解語法的工作。

  1. babel preset env 負責將ES6語法轉換成ES5
  2. babel preset react 負責將JSX語法轉化為JavaScript

安裝依賴:

npm i @babel/core babel-loader @babel/preset-env @babel/preset-react --save-dev複製程式碼

不要忘記配置Babel。在工程根目錄下建立.babelrc檔案,配置如下:

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}複製程式碼

現在,我們需要編寫一個簡短的webpack配置檔案。

建立webpack.config.js檔案,配置如下:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  }
};複製程式碼

對於每個帶有js或jsx副檔名的檔案,Webpack通過babel-loader管理程式碼,將ES6轉換為ES5。

有了這個,我們就可以編寫React元件了。


編寫React元件

首先按照Container/Presentation原則,建立兩個React元件。

容器元件是承載所有邏輯的元件:用於處理狀態更改的函式,內部元件狀態等。 相反,展示元件僅用於展示。 展示元件是普通的JavaScript函式,它從容器元件接收資料作為props。

下面,我將構建一個簡單的帶文字框的React表單。

編寫程式碼之前,需要安裝React:

npm i react react-dom --save-dev複製程式碼

接著,建立元件的目錄結構:

mkdir -p src/js/components/{container,presentational}複製程式碼

下面我們建立容器元件,需滿足以下條件:

  • 有自己的state
  • 渲染出來是一個HTML表單

建立元件:

touch src/js/components/container/FormContainer.jsx複製程式碼

程式碼如下:

import React, { Component } from "react";
import ReactDOM from "react-dom";

class FormContainer extends Component {
  constructor() {
    super();

    this.state = {
      title: ""
    };
  }

  render() {
    return (
      <form id="article-form">
      </form>
    );
  }
}

export default FormContainer;複製程式碼

這個元件目前沒有完成任何工作,它只是一個用於包含子元件的框架。

下面建立子元件:

touch src/js/components/presentational/Input.jsx複製程式碼

我們的展示元件是一個文字框。一個HTML文字框擁有以下屬性:

  • type
  • class
  • id
  • value
  • required

所有的這些屬性都應該由父容器元件傳入子元件。

如果input擁有自己的state,在使用時一定要注意,確保HTML input是一個受控的React元件。

安裝如下依賴:

npm i prop-types --save-dev複製程式碼

回到React元件,展示元件程式碼如下:

import React from "react";
import PropTypes from "prop-types";

const Input = ({ label, text, type, id, value, handleChange }) => (
  <div className="form-group">
    <label htmlFor={label}>{text}</label>
    <input
      type={type}
      className="form-control"
      id={id}
      value={value}
      onChange={handleChange}
      required
    />
  </div>
);

Input.propTypes = {
  label: PropTypes.string.isRequired,
  text: PropTypes.string.isRequired,
  type: PropTypes.string.isRequired,
  id: PropTypes.string.isRequired,
  value: PropTypes.string.isRequired,
  handleChange: PropTypes.func.isRequired
};

export default Input;複製程式碼

接下來,我們用容器元件包含這個展示元件:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import Input from "../presentational/Input.jsx";

class FormContainer extends Component {
  constructor() {
    super();

    this.state = {
      seo_title: ""
    };

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    this.setState({ [event.target.id]: event.target.value });
  }

  render() {
    const { seo_title } = this.state;
    return (
      <form id="article-form">
        <Input
          text="SEO title"
          label="seo_title"
          type="text"
          id="seo_title"
          value={seo_title}
          handleChange={this.handleChange}
        />
      </form>
    );
  }
}

export default FormContainer;複製程式碼

webpack預設的入口檔案為./src/index.js。我們建立這個檔案,並在入口檔案中引入容器元件FormContainer

import FormContainer from "./js/components/container/FormContainer.jsx";複製程式碼

然後,我們就可以執行如下命令進行打包:

npm run build複製程式碼

打包後的js檔案在./dist/main.js

現在讓我們將實現將打包檔案引入HTML頁面。


HTML webpack plugin

要使React form展示出來,我們必須要讓webpack建立一個HTML頁面,並且將打包後的js檔案引入HTML。

Webpacks需要兩個額外的元件來處理HTML:html-webpack-pluginhtml-loader

安裝依賴:

npm i html-webpack-plugin html-loader --save-dev複製程式碼

更新webpack配置檔案:

const HtmlWebPackPlugin = require("html-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: "html-loader"
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebPackPlugin({
      template: "./src/index.html",
      filename: "./index.html"
    })
  ]
};複製程式碼

建立./src/index.html檔案

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" >
    <title>How to set up React, Webpack, and Babel</title>
</head>

<body>
    <div class="container">
        <div class="row mt-5">
            <div class="col-md-4 offset-md-1">
                <p>Create a new article</p>
                <div id="create-article-form">
                    <!-- form -->
                </div>

            </div>

        </div>
    </div>
</body>

</html>複製程式碼

最後,將React元件掛在到id為create-article-form的元素上:

const wrapper = document.getElementById("create-article-form");
wrapper ? ReactDOM.render(<FormContainer />, wrapper) : false;複製程式碼

再次build:

npm run build複製程式碼

檢視dist目錄,你將會看到HTML結果檔案

使用webpack,不需要手動將js檔案引入HTML,打包後的檔案將會被自動注入。

開啟./dist/index.html,你將會在瀏覽器中看到剛剛編寫的React表單


Webpack dev server

如果你不想每次改變檔案的時候都執行npm run build來檢視結果,使用簡單的三行配置就可以啟動本地的開發伺服器。配置後,webpack將在瀏覽器中啟動應用程式。 此外,每次修改後儲存檔案webpack伺服器都會自動重新整理瀏覽器的視窗。

安裝依賴:

npm i webpack-dev-server --save-dev複製程式碼

更新package.json

"scripts": {
  "start": "webpack-dev-server --open --mode development",
  "build": "webpack --mode production"
}複製程式碼

執行命令:

npm start複製程式碼

你將會在瀏覽器中看到如下介面:

Webpack Dev Server

並且,每次更新檔案webpack dev server都會自動重新整理頁面。


總結

create-react-app是一種開啟React專案的方法,幾乎所有東西都是開箱即用。但遲早,你都會想要調整或修改一下原有的webpack配置。

如果你學習瞭如何手動配置React,webpack和Babel,你就可以根據自己的需要從零開始配置React專案。

這些知識對於不需要完整的SPA但仍希望構建和分發ES6程式碼的情況也很有用。 通過組合webpack和Babel,可以將一堆React元件轉換為適合分發的bundle。


原文連結:https://www.valentinog.com/blog/react-webpack-babel/


相關文章