项目初始化
yarn init -y
个人较为喜欢 yarn 作为包管理工具,可自行选择为 npm 或其他包管理器
安装 React 相关依赖
yarn add react react-dom
react: 类组件、函数组件、hooks、contexts、refs…这些都是 React 特性,即 React API。
react-dom:渲染器,负责在不同的宿主载体上实现特性,达到与描述相对应的真实效果。比如在浏览器上,渲染出DOM树、响应点击事件等。
安装 webpack 相关依赖
yarn add -D webpack webpack-cli webpack-dev-server
webpack:构建工具
webpack-cli:命令行运行 webpack 的工具
webpack-dev-server:开发服务器
安装 babel 相关依赖
yarn add babel-loader @babel/core @babel/preset-react
babel-loader:webpack 的加载器(loader),用于将 JavaScript 代码通过 Babel 进行转换。
@babel/core:Babel 的核心模块,它是 babel 编译器的主要部分。
@babel/preset-react:Babel 的一个预设(preset),用于转换 React 中的 JSX 语法。
注:React 17 之前需要引入 React,如:
1 import React from "react";React 17 之后不需要引入 React,可在运行时自动注入,但需要在
webpack.config.js
下进行相应配置:
Before React v17
1
2
3
4
5
6
7
8
9
10
11
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
options: {
presets: ["@babel/preset-react"]
}
},
]
}
After React v17
1
2
3
4
5
6
7
8
9
10
11
12
13
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
options: {
presets: [["@babel/preset-react", {
runtime: "automatic"
}]] // 注意这里是嵌套数组
}
},
]
}
创建 webpack 配置文件
在项目根目录下创建 webpack.config.js
,并在此文件中配置入口、出口、模块等。示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const path = require("path")
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
'publicPath': '/'
},
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
options: {
presets: ["@babel/preset-react"]
}
}
]
},
devServer: {
historyApiFallback: true,
hot: true,
port: 3456
}
}
创建项目文件结构
- 在项目根目录下创建一个名为
src
的文件夹。 - 在
src
文件夹中创建一个名为index.js
的文件,作为项目的入口文件。
创建 HTML 模板
- 在项目根目录下创建一个名为 public 的文件夹。
- 在 public 文件夹中创建一个名为 index.html 的文件,并在
body
中添加以下内容:
1
2
<div id="root"></div>
<script src="/bundle.js"></script>
编写基础代码
打开 src/index.js
文件并添加以下代码:
1
2
3
4
5
6
import React from 'react';
import { createRoot } from 'react-dom/client';
const container = document.getElementById('root');
const root = createRoot(container); // createRoot(container!) if you use TypeScript
root.render(<h1>Hello, React!</h1>);
React 18 引入了一个新的根 API,它为管理根提供了更好的人体工程学。新的根 API 还启用了新的并发渲染器,它允许您选择并发功能。
如果安装 v18 的 React,则需要以上创建根节点的方式,v18 之前使用 ReactDOM.render 即可。
运行开发服务器
- 打开终端或命令行界面,确保当前目录位于项目根目录。
- 执行此命令以启动开发服务器
npx webpack serve --mode development
可以在 package.json
中设置 scripts,以使用更简洁的命令行运行开发服务器
1
2
3
4
5
{
"scripts": {
"start": "npx webpack serve --mode development"
}
}
使用 loader 和 plugin 在不同环境下处理样式
yarn add css-loader style-loader mini-css-extract-plugin sass sass-loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/,
use: [ // 一定要注意在 webpack 中配置 loaders 的顺序,因为 loaders 总是从下到上执行
(
process.env.NODE_ENV === 'development'
? "style-loader" // 开发环境将 css-loader 转译出的 JS 字符串插入到页面的 style 标签
: MiniCssExtractPlugin.loader // 将样式代码抽离到单独产物文件,并以 <link> 标签方式引入到页面中
),
"css-loader", // 将 css 解析为 webpack 可理解的 js
"sass-loader" // 将 scss 解析为 css
]
}
]
},
plugins: [
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({ //
template: "public/index.html" // 需要指定模板 HTML 路径
})
]
}
这里需要注意几个点:
- mini-css-extract-plugin 库同时提供 Loader、Plugin 组件,需要同时使用
- mini-css-extract-plugin 不能与 style-loader 混用,否则报错,所以上述示例中第 9 行需要判断 process.env.NODE_ENV 环境变量决定使用那个 Loader
- mini-css-extract-plugin 需要与 html-webpack-plugin 同时使用,才能将产物路径以 link 标签方式插入到 html 中
使用 file-loader
和 @svgr/webpack
处理 react 中的静态资源
使用 file-loader
来处理各种图片静态资源
使用 @svgr/webpack
来处理 svg 文件,这样我们可以直接把 svg 当作组件方式来引入,并且可以设置相应的类名,示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import Svg from './assets/react.svg';
import styles from './styles.module.scss';
import masiwei from './assets/masiwei.png';
const App = () => {
return (
<div>
<div className={ styles.title }>
<Svg className={ styles.react }/>
<h1>Hello, React!</h1>
</div>
<div className={ styles.info }>
<img src={ masiwei } alt=""/>
</div>
</div>
)
}
export default App
两者的 webpack 配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module.exports = {
performance: {
maxAssetSize: 1000000, // 单个文件大小限制(字节)
maxEntrypointSize: 1000000, // 入口文件大小限制(字节)
},
module: {
rules: [
{
test: /\.(png|jpg|gif|webp)$/, // 匹配图片文件
use: ['file-loader'] // 使用 file-loader
},
{
test: /\.svg$/, // 单独配置 svg 文件 这样可直接作为组件使用
use: ['@svgr/webpack'],
}
]
}
}
其中加入了一个新属性
performance
,用于限制文件大小,单位:字节