這是一篇非常適合新手的教程。
目錄:
- 你將會學習到的知識
- 建立專案
- 配置webpack
- 配置Babel
- 編寫React元件
- HTML webpack plugin
- webpack dev server
- 總結
你將會學習到的知識
- 如何安裝及配置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語法轉換為瀏覽器所能理解語法的工作。
- babel preset env 負責將ES6語法轉換成ES5
- 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-plugin
和html-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都會自動重新整理頁面。
總結
create-react-app是一種開啟React專案的方法,幾乎所有東西都是開箱即用。但遲早,你都會想要調整或修改一下原有的webpack配置。
如果你學習瞭如何手動配置React,webpack和Babel,你就可以根據自己的需要從零開始配置React專案。
這些知識對於不需要完整的SPA但仍希望構建和分發ES6程式碼的情況也很有用。 通過組合webpack和Babel,可以將一堆React元件轉換為適合分發的bundle。
原文連結:https://www.valentinog.com/blog/react-webpack-babel/