<p align="center">
  <img width="320" src="https://i-blog.csdnimg.cn/direct/5239ae895cf54b51b73b0f9b46d5e025.png#pic_center">
</p>

[Github 地址]( https://github.com/diandian18/react-antd-console) | [文档地址]( https://doc.react-antd-console.site) | [预览地址]( https://react-antd-console.site)

<p align="center">
  <img width="100%" src="https://i-blog.csdnimg.cn/direct/19071fd08af0438c8a33ab4a68cf8f90.png#pic_center">
</p>

[react-antd-console]( https://github.com/diandian18/react-antd-console) 是一个后台管理系统的前端解决方案,封装了后台管理系统必要功能(如登录、鉴权、菜单、面包屑、标签页等),帮助开发人员专注于业务快速开发。项目基于 `React 18`、`Ant design 5`、`Vite` 和 `TypeScript` 等新版本。对于使用到的各项技术,会被持续更新至最新版本。可放心用于生产环境。

为了方便大家更好的掌握和使用本项目,推出系列文章:

- 腿夹腿,带你用 react 撸后台,系列一( Vite 篇)

如果你喜欢这个项目或认为对你有用,欢迎使用体验和 [Star]( https://github.com/diandian18/react-antd-console)

## 1. 概述

首先我们需要搞定构建工具问题,我们使用了 [Vite]( https://cn.vite.dev/) 作为构建工具

> Vite 是一个超快速的前端构建工具,推动着下一代网络应用的发展

Vite 最大的特点是启动极速(通常 1s 内)、轻量快速的热更新、对 TypeScript 、JSX 、CSS 等支持开箱即用。相较于 Webpack 传统构建工具,其配置极简,并同样可以实现我们想要的诸多功能,维护心智负担极低

### 1.1 Vite 的问题

如果一个构建工具存在瓶颈,那么哪怕其他有再好的方面,最终也无法选用。所以我们不能忽视 Vite 的缺点。那就是:

#### 1.1.1 刷新页面慢?

Vite 因为减少了源文件( JS/TS/CSS )的工作量,导致并发请求多而拖慢刷新页面的速度。但结合启动和热更新,在速度上,相比 Webpack ,本文档认为仍然具有明显的优势

本项目在开发启动后,刷新首页,共有 168 项请求,耗时 150 至 200 毫秒。作为参考

#### 1.1.2 开发和打包不一致?

理论上是有可能的,因为 Vite 开发使用 esbuild, 打包使用 rollup 。但实际情况中,作者从没有碰到过不一致的情况。而且 Vite 即将使用 [Rolldown]( https://rolldown.rs/) 作为底层打包工具。Rolldown 将保证开发和打包结果完全一致,并提供更快的打包速度。届时可平滑升级

## 2. Vite 内置

Vite 内置了很多开箱即用的功能,本项目用到的内置功能有:

- [npm 依赖解析和预构建]( https://cn.vite.dev/guide/features.html#npm-dependency-resolving-and-pre-bundling)
- [模块热替换]( https://cn.vite.dev/guide/features.html#hot-module-replacement)
- [TypeScript]( https://cn.vite.dev/guide/features.html#typescript)
- [客户端类型]( https://cn.vite.dev/guide/features.html#client-types)
- [JSX]( https://cn.vite.dev/guide/features.html#jsx)
- [CSS]( https://cn.vite.dev/guide/features.html#css)
- [JSON]( https://cn.vite.dev/guide/features.html#json)
- [动态导入]( https://cn.vite.dev/guide/features.html#dynamic-import)
- [CSS 代码分割]( https://cn.vite.dev/guide/features.html#css-code-splitting)
- [预加载指令生成]( https://cn.vite.dev/guide/features.html#preload-directives-generation)
- [异步 Chunk 加载优化]( https://cn.vite.dev/guide/features.html#async-chunk-loading-optimization)

### 2.1 样式

样式预处理器我们使用的是 [Less]( https://lesscss.org/)。在 Vite 中,只需要安装 less 模块即可直接使用

```shell
npm i -D less
```

本项目没有额外配置 less 选项,若需要进一步配置,可参考 [Vite 配置 css.preprocessorOptions]( https://cn.vite.dev/config/shared-options.html#css-preprocessoroptions)

#### 2.1.1 打包后,样式名自动加前缀

对于样式名,不同浏览器可能有不同的前缀,例如 `-webkit-`、`-ms-`、`-moz-` 等。但我们写代码时并不想写这些前缀,但打包时可以自动生成。Vite 中如果项目包含有效的 PostCSS 配置 (任何受 postcss-load-config 支持的格式,例如 postcss.config.cjs),它将会自动应用于所有已导入的 CSS 。

安装 PostCSS 插件 [autoprefixer]( https://github.com/postcss/autoprefixer)

```shell
npm i -D autoprefixer
```

在 `<root>/postcss.config.cjs` 中配置自动前缀插件即可生效:

```ts
// postcss.config.cjs
module.exports = {
  plugins: [
    require('autoprefixer'),
  ],
};
```

参考文档:

- [Vite 配置 PostCSS]( https://cn.vite.dev/guide/features.html#postcss)

### 2.2 入口

- html 入口为根目录的 `<root>/index.html`,可在该 html 中引入入口 ts/tsx 文件
- 入口 ts/tsx 文件 位于 `src/main.tsx`,在该文件中,初始化了 react 等

说明:

- 在开发时,访问本地服务根路径,会返回上述 html 文件
- 在打包后,根目录的 `<root>/dist` 文件夹中也会包含打包后的 html 文件,其源码被引入的 ts/tsx 文件和路径,会被自动转换成打包后的文件和路径

打包前:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="shortcut icon" type="image/x-icon" href="/images/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>react-antd-console</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>
```

打包后:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="shortcut icon" type="image/x-icon" href="/images/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>react-antd-console</title>
    <script type="module" crossorigin src="/assets/index-B68Xj7Fq.js"></script>
    <link rel="stylesheet" crossorigin href="/assets/index-CHnsXl1V.css">
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
```

### 2.3 打包

当我们通过 `package.json` 中的 `npm run build:prod` 命令打包时,其实是调用了 `vite build --mode prod`命令。默认情况下,它使用 `<root>/index.html` 作为其构建入口点,并生成能够静态部署的应用程序包 `<root>/dist/`。若要部署,我们将打完的包放到 nginx 等服务上即可

我们还可以指定打包后的文件所支持的浏览器目标,例如指定为支持 `es2015` 浏览器

```ts
// vite.config.js
export default defineConfig({
  build: {
    target: 'es2015',
  },
})
```

参考文档:

- [Vite 构建生产版本]( https://cn.vite.dev/guide/build.html#building-for-production)

### 2.4 public 目录

[public 目录]( https://cn.vite.dev/guide/assets.html#the-public-directory) 位于根目录的 `<root>/public` 文件夹。该目录中的资源在开发时能直接通过 / 根路径访问到,并且打包时会被完整复制到目标目录的根目录下

## 3. Vite 配置

另外有些功能是需要配置的,Vite 配置极其简洁。配置文件位于根目录的 `<root>/vite.config.ts` 如下:

```ts
// vite.config.ts
export default defineConfig({
  plugins: [
    react(),
    createSvgIconsPlugin({
      iconDirs: [path.resolve(process.cwd(), 'src/assets/svg')],
      symbolId: 'icon-[dir]-[name]',
    }),
  ],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
      '@@': path.resolve(__dirname, './examples'),
    },
  },
  server: {
    host: true,
    port: 9527,
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },
  esbuild: {
    target: 'chrome65',
  },
  build: {
    target: 'es2015',
  },
});
```

以下功能为配置后生效的功能:

### 3.1 开发服务

```ts
// vite.config.js
export default defineConfig({
  server: {
    host: true,
    port: 9527,
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },
})
```

- [server.host]( https://cn.vite.dev/config/server-options.html#server-host) 指定服务器应该监听哪个 IP 地址。 如果将此设置为 0.0.0.0 或者 true 将监听所有地址,包括局域网和公网地址
- [server.port]( https://cn.vite.dev/config/server-options.html#server-port) 指定开发服务器端口
- [server.proxy]( https://cn.vite.dev/config/server-options.html#server-proxy) 为开发服务器配置自定义代理规则。具体配置继承自 [http-proxy]( https://github.com/http-party/node-http-proxy#options)。
  - 解释: 当请求 `/api` 开头的 url 时,该请求会被代理到 `http://localhost:3000` ,并且请求路径会自动去除 `/api`

启动服务后,Vite 会使用 [esbuild]( https://esbuild.github.io/) 作为编译工具,我们指定下编译的文件所支持的浏览器版本为 `chrome65` 以上:

```ts
// vite.config.js
export default defineConfig({
  esbuild: {
    target: 'chrome65',
  },
})
```

### 3.2 react 支持

使用官方的 react 插件 [@vitejs/plugin-react]( https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react),支持:

- 在开发中启用热更新 (需要 react >= 16.9)
- 使用自动 JSX 运行时
- 使用安装体积小的自定义 Babel 插件/预设

```ts
// vite.config.js
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
})
```

### 3.3 路径别名

`import` 文件时,我们常常会把 `<root>/src` 别名为 `@`,这样编写代码就比较方便

```ts
// vite.config.js
export default defineConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
})
```

### 3.4 多环境

多环境采用 `vite` 内置的方案。

- 当使用 `vite --mode localhost` 启动项目时,环境的配置文件,对应的是根目录的 `<root>/.env.localhost` 文件。
- `.env.localhost` 文件中定义的环境变量,可通过 `const { VITE_API_HOST } = import.meta.env` 在代码中引入。

#### 如何新增环境,并新增环境变量?

1. 在根目录新建 `.env.newEnv` 文件
2. 在 `.env.newEnv` 文件中定义环境变量: `VITE_SOME_KEY = someValue`
3. 在 `src/vite-env.d.ts` 定义 `VITE_SOME_KEY` 的类型
4. 在项目的 `ts/tsx` 文件中引入环境变量 `const { VITE_SOME_KEY } = import.meta.env;`

#### 3.4.1 指定环境构建

添加构建命令:

```json
// package.json
{
  "scripts": {
    "build:newEnv": "vite build --mode newEnv",
  }
}
```

执行构建:

```shell
npm run build:newEnv
```

## 4. 其他 Vite 不相关的工程化配置

### 4.1 编码规范

项目总体按最小约束原则约束编码规范,只使用了 `eslint`。你可以根据自己的需求自行添加各规范,如 [stylelint]( https://stylelint.io/)、[prettier]( https://prettier.io/) 等

> [!TIP]
> 我们认为在编码规范方面,应当在工程**统一性**和**灵活性**之间找到一个平衡,而不是一味地使用各种 lint 类工具作强制约束。你可以找到自己团队的平衡点,定制适合自己团队的编码规范

#### 4.1.1 eslint 规则

本项目采用官方建议的通用 `eslint` 规则,如下:

- `@typescript-eslint/recommended` (`eslint` 官方赞助的社区 `typescript` 规则)
- `eslint:recommended` (`eslint` 官方推荐规则)
- `eslint-plugin-react` (社区流行的 `react` 规则)

详见 `<root>/.eslintrc.cjs`

[eslint]( https://eslint.org/) 可配合 [husky]( https://typicode.github.io/husky/)、[lint-staged]( https://github.com/lint-staged/lint-staged) 实现 `git commit` 时自动校验 `eslint`,其他文档和教程很多,在此不再赘述

## 5. 完整版预览

### 5.1 深/浅色主题

| <img src="https://i-blog.csdnimg.cn/direct/d8f7ddb346b44945831b18f6c129613d.png#pic_center"> | <img src="https://i-blog.csdnimg.cn/direct/359c7c33fc0346368a3f038d19f5182f.png#pic_center"> |
| --- | --- |
| Light | Dark |

### 5.2 任意主色切换

| <img src="https://i-blog.csdnimg.cn/direct/4af0d1134416407dbb29cdb0e633dacc.png#pic_center"> | <img src="https://i-blog.csdnimg.cn/direct/a5bf6c5b865b4ed185fc980972cbdcc5.png#pic_center"> |
| --- | --- |

| <img src="https://i-blog.csdnimg.cn/direct/d7bb1e94684b4fa28a6c1027944f4d2c.png#pic_center"> | <img src="https://img-blog.csdnimg.cn/img_convert/2f9768b7e83801a923d8070ad0df596e.png#pic_center"> |
| --- | --- |

### 5.3 任意背景色切换

| <img src="https://i-blog.csdnimg.cn/direct/0097d6640e9242a09a3b5b7a0ba3ddf6.png#pic_center"> | <img src="https://img-blog.csdnimg.cn/img_convert/b8b156b282fa9657def443d77ebf7b24.png#pic_center"> |
| --- | --- |
| Background Light | Background Dark |

### 5.4 4 种布局

| <img src="https://i-blog.csdnimg.cn/direct/e81c04059d314a9c8deaec3dc5aa613d.png#pic_center"> | <img src="https://i-blog.csdnimg.cn/direct/ca2a3390eec04658add273ff5333b49a.png#pic_center"> |
| --- | --- |
| 侧分栏 | 侧单栏 |

| <img src="https://img-blog.csdnimg.cn/img_convert/f8e37200dc4916ed100cbc476a1342d7.png#pic_center"> | <img src="https://img-blog.csdnimg.cn/img_convert/83afc6f1f812f0b16be4457b4ee2410b.png#pic_center"> |
| --- | --- |
| 头分栏 | 头单栏 |

### 5.5 丰富的主题配置

<img width="100%" src="https://i-blog.csdnimg.cn/direct/16c002425d3f46478f5764c4733591ea.png#pic_center">

## 6. 系列文章

- 腿夹腿,带你用 react 撸后台,系列一( Vite 篇)

如果你喜欢这个项目或认为对你有用,欢迎使用体验和 [Star]( https://github.com/diandian18/react-antd-console)

[Github 地址]( https://github.com/diandian18/react-antd-console) | [文档地址]( https://doc.react-antd-console.site) | [预览地址]( https://react-antd-console.site)
举报· 518 次点击
登录 注册 站外分享
41 条回复  
russ44 初学 2024-10-24 11:05:08
cool
cbythe434 初学 2024-10-24 11:07:45
腿夹腿撸和手把手撸体验上有差吗
ZGame 初学 2024-10-24 11:15:08
挺好看的 学习一下
michaelluang 初学 2024-10-24 11:15:50
写得很棒,期待下一篇。
zclzone 初学 2024-10-24 11:26:32
写得很好,已 star ,顺便推荐一下 vue-naive-admin ,使用 vue3 + vite ,https://github.com/zclzone/vue-naive-admin
starcoming 小成 2024-10-24 11:31:57
支持一下
shintendo 小成 2024-10-24 11:47:35
但实际情况中,作者从没有碰到过不一致的情况
------
有一个挺常见的坑,开发和打包后的 CSS 顺序不一致,相关 issue 开了 4 年了至今未解决
Ma4cus 初学 2024-10-24 13:42:53
厉害了,有 vue 的吗
ColdBird 小成 2024-10-24 13:50:31
还好不是手把腿
12345下一页
返回顶部