這是一篇很是適合新手的教程。css
目錄:html
首先,建立工程目錄:前端
mkdir webpack-react-tutorial && cd $_複製代碼
建立工程的基礎目錄結構:node
mkdir -p src複製代碼
初始化項目:react
npm init -y複製代碼
webpack是一款很是強大的工具,學習webpack不只能夠用於搭建React項目,它適用於任何前端工程。webpack
webpack提取原始的React組件,用於生成(幾乎)每一個瀏覽器都能理解的JavaScript代碼。
web
安裝webpack:npm
npm i webpack --save-dev複製代碼
同時須要安裝webpack-cli:json
npm i webpack-cli --save-dev複製代碼
下一步,在package.json
中添加webpack命令:bootstrap
"scripts": {
"build": "webpack --mode production"
}複製代碼
如今你不須要爲webpack定義配置文件。
老版本的webpack不會自動查找配置文件,但從webpack4開始,不須要配置文件就能夠直接進行開發。
接下來我將安裝並配置Babel來編譯咱們的代碼。
React組件大可能是由ES6語法編寫。ES6是對語法的一次很好的改進,但老版本瀏覽器每每不能解析新的ES6語法。有狀態的React組件被生命爲class,所以,爲了讓ES6在舊版瀏覽器中運行,咱們須要進行某種轉換。咱們把這種轉換成爲編譯。
webpack並不知道如何將ES6語法轉換爲ES5,不過webpack可使用loader來完成。即webpack加載器將一些東西做爲輸入,並將其轉換爲其餘東西輸出。
webpack中的babel-loader便擔任着將ES6語法轉換爲瀏覽器所能理解語法的工做。
安裝依賴:
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組件了。
首先按照Container/Presentation原則,建立兩個React組件。
容器組件是承載全部邏輯的組件:用於處理狀態更改的函數,內部組件狀態等。 相反,展現組件僅用於展現。 展現組件是普通的JavaScript函數,它從容器組件接收數據做爲props。
下面,我將構建一個簡單的帶文本框的React表單。
編寫代碼以前,須要安裝React:
npm i react react-dom --save-dev複製代碼
接着,建立組件的目錄結構:
mkdir -p src/js/components/{container,presentational}複製代碼
下面咱們建立容器組件,需知足如下條件:
建立組件:
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文本框擁有如下屬性:
全部的這些屬性都應該由父容器組件傳入子組件。
若是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頁面。
要使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表單
若是你不想每次改變文件的時候都執行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/