轉自IMWeb社群,作者:黃qiong,原文連結
前言
看到一篇還不錯的文章,翻譯(也不是完全翻譯,還是改動了一點點讓它變得更易理解)了一波,想看原文的移步這裡。
順便推薦一下這個小哥的文章都寫的挺好的~。
你會在本篇學到什麼
1.如何安裝配置webpack
2.如何安裝配置babel
3.如何安裝react
4.如何建立兩種React Component --- 容器/展示元件
5.在html檔案中引用webpack生成的bundle檔案
6.如何安裝使用webpack dev server
初始化專案
首先我們先給專案建立一個資料夾 webpack-react-tutorial
:
mkdir webpack-react-tutorial && cd webpack-react-tutorial
接著在這個資料夾下建立一個src的子資料夾:
mkdir -p src
初始化專案:
npm init -y
如何安裝配置webpack
webpack
webpack是一款非常有用的前端打包工具,瞭解如何使用它是React開發者的基礎,因為webpack可以將React元件轉化成幾乎所有瀏覽器都可以執行的JS code。
讓我們先來安裝它:
npm i webpack --save-dev
你可能會需要webpack-cli,所以也先裝上
npm i webpack-cli --save-dev
接著在package.json裡新增webpack的指令
"scripts": {
"build": "webpack --mode production"
}
複製程式碼
到目前為止還不需要寫webpack的配置檔案。
下面我們來安裝和配置Babel來編譯我們的程式碼。
初始化Babel
為什麼要使用Babel?
React Component大多是用JS ES6語法來寫的,而有些瀏覽器沒辦法執行ES6的語法,所以就需要工具來將ES6的程式碼轉化成瀏覽器可以執行的程式碼(通常是es5的語法)。
webpack本身是不會做這件事情的,需要靠轉換器:loader。
一個webpack loader作用就是把輸入進去的檔案轉化成指定的檔案格式輸出。其中babel-loader負責將傳入的es6檔案轉化成瀏覽器可以執行的檔案。
babel-loader需要利用Babel,所以需要預先將Babel配置好。
babel preset env:將ES6的程式碼轉成ES5(注意:babel-preset-es2015已經被廢棄了)
2.babel preset react: 將JSX語法編譯成JS
接著安裝這兩個依賴:
npm i @babel/core babel-loader @babel/preset-env @babel/preset-react --save-dev
不要忘了配置Babel! 首先要在webpack-react-tutorial資料夾裡新建一個檔案.babelrc,內容為
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
複製程式碼
到這個時候,就可以寫一小部分webpack的配置檔案了。
建立一個新的檔案webpack.config.js,內容為
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
複製程式碼
這個webpack的配置很簡單。意思就是所有以.js結尾的檔案都會用babel-loader把ES6編譯轉化成ES5的檔案。
同時它定義了輸入檔案的路徑為 src/index.js,輸出為dist/bundle.js。webpack 4裡這兩行程式碼你不寫也行,webpack會預設幫你加,但是為了程式碼可讀性,我們還是把它加上。
配置完成之後,我們就可以開始寫React 元件了。
寫React元件
這裡會寫兩種React元件:容器、展示元件。如果不瞭解這兩種元件概念的同學可以先了解一下。
簡單來說: 容器跟展示元件是React元件的兩種模式。
容器元件: 一般比較重資料處理的邏輯會寫在這,比如監聽外界傳入(例如redux) state的變化,或者處理元件內部的state,等等。
展示元件:顧名思義,就是僅僅用來展示的。它一般都是一個純箭頭函式,接受容器元件通過props傳來的資料,然後展示我們希望展示的html結構。
在下面的例子中,你會看到它們長啥樣。
在本節中,我們來建立只有text input 的超級簡單的React表單。
首先先把React庫引進來:
npm i react react-dom --save-dev
然後建立兩個子資料夾來分別放React 容器/展示元件
mkdir -p src/js/components/{container,presentational}
接著我們來寫一個容器元件,它有下面的特點
- 有自己的state
- 渲染一個html表單
將這個容器元件放在container裡
touch src/js/components/container/FormContainer.js
容器元件的程式碼如下:
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;
複製程式碼
到目前為止,這個元件還沒啥用,它只是一個包裹著子展示元件的外殼。
所以我們來定義一下子元件Input吧。
我們知道html input有下列的屬性:
- type
- class
- id
- value
- required
所有的這些屬性都由容器元件通過props傳給它,這種元件叫做controlled component。
寫一個react元件,最好給它加上Prop Types,這樣一來可以做輸入的資料型別檢測,二來別人用你的元件,可以很快知道這個元件需要什麼input。
安裝prop-types
npm i prop-types --save-dev
接著寫這個展示元件
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;
複製程式碼
到這一步我們就可以在容器元件裡渲染Input這個子元件了
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Input from "../presentational/Input";
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來打包這些程式碼啦。
由於前面我們已經定義了webpack入口檔案是 ./src/index.js,所以我們先建立一個index.js檔案,在裡面引入React元件
import FormContainer from "./js/components/container/FormContainer";
複製程式碼
寫好之後,激動人心的時刻到了! 我們終於可以通過執行 npm run build
來生成打包檔案,由於我們在配置裡定義了輸出檔案為:dist/bundle.js,所以一切順利的話, 你現在應該可以看到一個新生成的dist檔案,裡面有一個bundle.js檔案。
在HTML檔案引入bundle
為了展示我們的React元件,我們需要讓webpack生成一個html檔案。上面我們生成的bundle.js就會放在這個html檔案的script
標籤裡。
webpack需要兩個工具來生成這個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$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader"
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
title: 'Set Up Project',
filename: "./index.html"
})
]
};
複製程式碼
index.html是我們的模板檔案,裡面定義了React Component需要插入進入的容器<div>create-article-form</div>
,不要忘了在FormContainer裡用React.render繫結這個。
<!doctype html>
<html>
<head>
<title>Getting Started</title>
</head>
<body>
<div id='create-article-form'>
</div>
</body>
</html>
複製程式碼
在./src/js/components/container/FormContainer.js 加上下面的程式碼:
const wrapper = document.getElementById("create-article-form");
wrapper ? ReactDOM.render(<FormContainer />, wrapper) : false;
複製程式碼
最後,在跑一次構建: npm run build
這時候在dist資料夾裡就會看到生成的html檔案,由於html-webpack-plugin,bundle檔案會被自動注入html裡。 在瀏覽器裡開啟./dist/index.html,你會看到這個React表單。
webpack dev Server
目前為止,我們來遺留一個問題:每次修改檔案的時候,都需要重新跑一次編譯
npm run build
這樣是很麻煩的,我們想達到的效果是自動重新編譯。 達到這個目標很簡單,只需要3行配置就可以啟動執行一個開發伺服器。
啟動伺服器之後webpack就會在瀏覽器裡啟動你的應用,而且當你修改儲存程式碼之後,webpack dev server還會自動重新整理瀏覽器的視窗。
在啟動webpack dev server前,需要先安裝npm i webpack-dev-server --save-dev
開啟package.json 加入start script
"scripts": {
"start": "webpack-dev-server --open --mode development",
"build": "webpack"
}
複製程式碼
儲存這個檔案,最後在跑這個命令 npm start
你會在你的瀏覽器裡看到你的應用。
接下來你可以隨意修改一下檔案內容,會看到webpack dev server會自動重新整理瀏覽器視窗。
總結
通過上面的學習,我們已經看到如何從零用webpack 與Babel搭建一個React專案,包括
- 如何安裝配置webpack
- 如何安裝配置Babel
- 如何安裝React
- 如何建立React容器/展示元件
- 如何在html裡插入bundle檔案
- 如何安裝和配置webpack dev server
如果你想了解更多webpack 4的知識,可以移步這篇文章。
參考文件:Tutorial: How to set up React, Webpack 4, and Babel 7 (2018)