轉自IMWeb社區,做者:黃qiong,原文連接html
看到一篇還不錯的文章,翻譯(也不是徹底翻譯,仍是改動了一點點讓它變得更易理解)了一波,想看原文的移步這裏。前端
順便推薦一下這個小哥的文章都寫的挺好的~。node
1.如何安裝配置webpackreact
2.如何安裝配置babelwebpack
3.如何安裝reactes6
4.如何建立兩種React Component --- 容器/展現組件web
5.在html文件中引用webpack生成的bundle文件npm
6.如何安裝使用webpack dev serverjson
首先咱們先給項目建立一個文件夾 webpack-react-tutorial
:redux
mkdir webpack-react-tutorial && cd webpack-react-tutorial
接着在這個文件夾下建立一個src的子文件夾:
mkdir -p src
初始化項目:
npm init -y
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?
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組件的兩種模式。
容器組件: 通常比較重數據處理的邏輯會寫在這,好比監聽外界傳入(例如redux) state的變化,或者處理組件內部的state,等等。
展現組件:顧名思義,就是僅僅用來展現的。它通常都是一個純箭頭函數,接受容器組件經過props傳來的數據,而後展現咱們但願展現的html結構。
在下面的例子中,你會看到它們長啥樣。
在本節中,咱們來建立只有text input 的超級簡單的React表單。
首先先把React庫引進來:
npm i react react-dom --save-dev
而後建立兩個子文件夾來分別放React 容器/展現組件
mkdir -p src/js/components/{container,presentational}
接着咱們來寫一個容器組件,它有下面的特色
將這個容器組件放在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有下列的屬性:
全部的這些屬性都由容器組件經過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文件。
爲了展現咱們的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表單。
目前爲止,咱們來遺留一個問題:每次修改文件的時候,都須要從新跑一次編譯
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 4的知識,能夠移步這篇文章。
參考文檔:Tutorial: How to set up React, Webpack 4, and Babel 7 (2018)