这是一篇非常适合新手的教程。
目录:
- 你将会学习到的知识
- 建立项目
- 配置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/