✋手摸手系列(一/1):react后台系统(从0开始)

4/25/2021 vitereact

# 第一篇

# 脚手架搭建

#

# highlight: a11y-dark

参考文献:https://vitejs.dev/config/#esbuild 项目地址:https://github.com/wowhoonet/vite-react-mobx-admin

# 后台系列目录

  1. # ✋手摸手系列(一/1): vite react typescript reactHook mobx(非脚手架)(从0开始)(包含路由权限控制) (opens new window)

  2. # ✋手摸手系列(一/2): vite react typescript reactHook mobx(非脚手架)(从0开始):路由和权限搭建 (opens new window)

# !!!vite 比较易懂,不讲概念了直接开整

# 搭建开始

  1. # 初始化项目

mkdir vite_react_mobx
cd vite_react_mobx
yarn init -y
1
2
3
  1. # 安装依赖

# 开发依赖

yarn add vite typescript -D
1

# 生产依赖

yarn add react react-dom
1

# package.json 如下所示

{
  "name": "vite_react_mobx",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "dev": "vite"
  }, // 加入执行脚本
  "devDependencies": {
    "typescript": "^4.2.4",
    "vite": "^2.2.1"
  },
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  1. # 开发开始

# 根目录新建 index.html, index.tsx 两个文件

image.png 可以看到我在 body 元素下面引入了 index.tsx 文件,需要注意的是 type="module"

<script type="module" src="./index.tsx"></script>
1

# 在 index.tsx 开始编写 typescript 代码

需要注意的是:开发之前需要准备类型推导文件(@types),仅仅是为了敲代码有提示;所以此时 package.json 文件就变成了

{
  "name": "vite_react_mobx",
  "version": "1.0.0",
  "scripts": {
    "dev": "vite", 
  },
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "typescript": "^4.2.4",
    "vite": "^2.2.1"
  },
  "dependencies": {
    "@types/node": "^14.14.37",
    "@types/react": "^17.0.3",
    "@types/react-dom": "^17.0.3",
    "@types/react-router": "^5.1.13",
    "@types/react-router-dom": "^5.1.7",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

加入到 package.json 之后记得 yarn 转一下依赖哦

# 开始开发我们的 index.tsx 文件咯

import React from 'react';
import ReactDom from 'react-dom';

ReactDom.render(
  <div>我是 vite</div>,
  document.querySelector('#app')
)
1
2
3
4
5
6
7

# 执行我们的 命令

yarn dev
1

image.png

# 正文开始

下面我从几个方面开始讲:

  1. 配置 vite(讲每一个配置的目的和作用)
  2. 配置 tsconfig
  3. 搭建项目框架

# vite 配置

# 根目录新建 vite.config.ts

# 开始配置 vite.config.ts

const path = require("path");
import reactRefresh from "@vitejs/plugin-react-refresh"; // 热更新
import { defineConfig } from 'vite'; // 自带的默认配置
import html from 'vite-plugin-html'; // 生成自定义 html,主要是在 html 中插入ico,title 等自定义动作
import vitePluginImp from 'vite-plugin-imp'; // 按需加载
import autoprefixer from 'autoprefixer'; // 浏览器兼容 css自动加前缀(比如::wikit-xxx)

const isDev = process.env.NODE_ENV === 'development';
const isProd = process.env.NODE_ENV === 'production';
const port = 3000; 

export default  defineConfig({
  root: process.cwd(), // index.html 的目录,默认查找的目录 
  base: "/", // 静态资源的目录
  mode: process.env.NODE_ENV, // 'production' | 'development' | 'none'
  define: {
    "process.env": {
      BUILD_ENV: process.env.BUILD_ENV || "beta", // 自定义参数
    },
  }, // 定义
  plugins: [
    reactRefresh(), // 热更新插件
    html({
      minify: true,
      inject: {
        injectData: {
          title: 'injectData title'
        }
      } // 注入 title,并压缩
    }),
    vitePluginImp({
      libList: [
        {
          libName: 'antd',
          style: (name) => {
            return`antd/lib/${name}/style/index.css`
          },
        }
      ]
    }) // 配置 antd 按需加载
  ], // 插件
  publicDir: 'public', // 静态资源目录,打包原封不动的目录
  resolve: {
    alias: {
      "@": path.resolve("src"),
    }, // 别名
    dedupe: [], // 重复依赖
    conditions: [], // 导出 计算
    extensions: [".js", ".jsx", ".ts", ".tsx", ".json"], // 省去拓展名的类型
  },
  css: {
    modules: {
      // localsConvention: "camelCaseOnly", // 模块 css 导出时用 驼峰(我不喜欢)
    },
    postcss: {
      // parser
      plugins: [
        autoprefixer({
          "overrideBrowserslist": ['last 2 versions'],
          grid: true
        }) // 自动前缀
      ]
    },
    preprocessorOptions: {

    },
  },
  logLevel: isDev ? 'info' : 'error',
  server: {
    hmr: true,
    port: port,
    open: true,
    proxy: {
      "^/api": {
        target: "https://test.api.order.iduoliao.cn",
        changeOrigin: true,
        ws: false,
        'secure': false,
        rewrite: (path) => path.replace(/^\/api/, '')
      },
    },
  }, // devServer 配置
  build: {
    // target: ""
    outDir: 'dist',
    assetsInlineLimit: 4096, // 在多少 kb 使用 base64
    cssCodeSplit: true, // css 拆分
    sourcemap: isDev ? 'inline' : false,
    minify: isProd ? 'terser': 'esbuild', // 使用打包器 terser打包效果好,但是打包速度慢  esbuild打包快
    terserOptions: {
      compress: true,
      ie8: false,
      format: {
        comments: false,
      }
    },
    cleanCssOptions: {
      level: 1,
    },
    write: true, // 将依赖资源写入到磁盘里面
    brotliSize: true, // 压缩报告
    chunkSizeWarningLimit: 500, //
  },
  optimizeDeps: {
    // entries: // 指定入口 index.html,
    
  }
});

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

# ts 配置

# 根目录新建 tsconfig.json

{
  "isolatedModules": true, // 每个文件都是单独的模块
  "compilerOptions": {
    "target": "esnext", // 目标为 esnext 版本
    "lib": ["dom", "esnext"], // 依赖库
    "jsx": "react", // jsx 编译成 react
    "module": "esnext", 
    "allowJs": true, 
    "moduleResolution": "node",
    "isolatedModules": false,
    "emitDecoratorMetadata": true, // 使用装饰器
    "experimentalDecorators": true,
    "noImplicitAny": true,
    "noImplicitThis": false,
    "strictNullChecks": false,
    "removeComments": false, // 移除注释
    "suppressImplicitAnyIndexErrors": true,
    "allowSyntheticDefaultImports": true,
    "typeRoots": ["node_modules/@types", "global.d.ts"], // 类型推导文件
    "baseUrl": "./", 
    "paths": {
      "@/*": ["src/*"]
    }, // 将 @/* 编译成 src/*
    "esModuleInterop": true,
    "types": ["vite/client", "node"], // 类型推导库
  },
  "exclude": ["node_modules", "dist"] // 哪些文件不需要打包
  // "include": [
  //   "**/*.tsx",
  //   "**/*.ts",
  // ]
}
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
27
28
29
30
31
32

# 需要再补充一下依赖 package.json

{
  "devDependencies": {
    "typescript": "^4.2.4",
    "vite": "^2.2.1",
    "@vitejs/plugin-react-refresh": "^1.3.1",
    "vite-plugin-html": "^2.0.3",
    "vite-plugin-imp": "^2.0.5"
  },
  "dependencies": {
    "@types/node": "^14.14.37",
    "@types/react": "^17.0.3",
    "@types/react-dom": "^17.0.3",
    "@types/react-router": "^5.1.13",
    "@types/react-router-dom": "^5.1.7",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "autoprefixer": "^10.2.5",
    "less": "^4.1.1",
    "less-loader": "^8.0.0"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

vite 默认内置了 less/sass,但需要安装 less lessloader 方可使用

# 重新安装依赖

yarn 
1

# 创建 view 页面文件夹

image.png

# 将主目录的 index.tsx 修改一下 如下:

import App from '@/view/App';
import React from 'react';
import ReactDom from 'react-dom';

ReactDom.render(
  <App></App>,
  document.querySelector('#app')
)
1
2
3
4
5
6
7
8

重新启动

yarn dev
1

# !恭喜,这时候已经可以看到效果了

# 太晚了,明天继续写 权限控制, see u, 第一次写文章,有什么问题或者不理解的或者不对的可以评论告诉我, 代码晚点上传 github,持续更新

Last Updated: 4/25/2021, 10:24:18 AM