从零搭建一个React18+Vite4+Antd5+React-router-dom6新项目

1,370 阅读3分钟

一、新建模板、安装项目所需依赖

  • 用vite脚手架新建一个项目 npm create vite@latest
  • 安装依赖 npm i
  • 按需安装依赖 npm install antd less react-router-dom axios recoil --save
  • 启动项目 npm run dev
  • 根据自己的习惯整理添加文件夹

        以前全局安装过vite3.0版本,但当前项目用的是4.0版本,所以启动项目的时候不能直接直接输入vite命令,版本不兼容启动会报错,建议使用package.json中的命令:npm run dev ; vite使用less 不需要再安装使用less-loader;也不需要再在每一页代码中引入import React from 'react'

二、配置路由

  • main.js中引入BrowserRouter包裹在最外层
  • 创建router组件,在main.js中引入Router,路由信息存储在router组件中
  • Router组件内容:
import { lazy, createElement, Suspense, Component, ComponentType } from "react";
import { Routes, Route, Navigate } from "react-router-dom";
import BasicLayout from "../components/Layout/BasicLayout";
import NotFound from "../pages/NotFound/NotFound";

// 这是正常懒加载写法 在引入时需要用<Suspense><Home/></Suspense>
// const Home = lazy(() => import("../pages/Home/Home"));
// const Course = lazy(() => import("../pages/Course/Course"));

// 封装懒加载组件 lazy与Suspense配合使用
const lazyElement = (
  element: () => Promise<{ default: ComponentType<any> }>
) => (
  <Suspense fallback={<>loading...</>}>{createElement(lazy(element))}</Suspense>
);

export default function routes() {
  return (
    <Routes>
      <Route path="/" element={<BasicLayout />}>
        {/* 重定向首页为Home页 */}
        <Route
          path=""
          element={lazyElement(() => import("../pages/Home/Home"))}
        />
        <Route
          path="home"
          element={lazyElement(() => import("../pages/Home/Home"))}
          index
        />
        <Route
          path="home/second"
          element={lazyElement(() => import("../pages/Home/HomeSecond"))}
        />
   
        <Route
          path="course"
          element={lazyElement(() => import("../pages/Course/Course"))}
        />
        <Route path="*" element={<NotFound />} />
      </Route>
    </Routes>
  );
}
  • 当后期添加的路由较多时,可以把路由信息抽出来成一个数组单独维护,创建routerConfig.tsx文件
// 定义routerConfig类型
interface routerConfigType {
    path: string;
    element: ReactNode;
    children?: routerConfigType[];
  }
  
const routerArr: routerConfigType[] = [
    {
      path: "/",
      element: <BasicLayout />,
      children: [
        {
          path: "",
          element: lazyElement(() => import("../src/pages/Home/Home")),
        },
        {
          path: "home",
          element: lazyElement(() => import("../src/pages/Home/Home")),
          children: [
            {
              path: "second",
              element: lazyElement(
                () => import("../src/pages/Home/HomeSecond")
              ),
            },
          ],
        },
        {
          path: "*",
          element: <NotFound />,
        },
      ],
    },
    {
      path: "login",
      element: lazyElement(() => import("../src/pages/Login/Login")),
    },
  ];

最外层是layout组件,路由为'/',其他需要在layout内的页面都放在layout的children里;不需要layout的,比如登录页,与layout平级。在router.tsx中处理routerConfig数组

import routerConfig from "../../config/routerConfig";
import routerConfigType from "../../global.d";

const getRoutes = (list: routerConfigType[]) => {
    return list.map((route) => {
      return (
        <Route path={route.path} element={route.element} key={route.path}>
          {route?.children && getRoutes(route.children)}
        </Route>
      );
    });
  };
return <Routes>{getRoutes(routerConfig)}</Routes>;

三、vite.config及tsconfig配置

vite.config.ts配置:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import * as path from "path";

export default defineConfig(({ command, mode }) => {
  return {
    plugins: [react()],// react()配置后不需要每页再import React from 'react'
    css: {
      modules: {
        // 配置css编译后在浏览器中的类名
        generateScopedName:
          mode === "development" ? "[path][name]__[local]" : "[local]",
      },
    },
    resolve: {
      alias: {
        "@": path.resolve(__dirname, "src"), // 别名配置后,在tsconfig中也需要配置相应的别名
      },
      extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json"], // 默认值,这些文件引入时不需要写后缀
    },
    server: {
      host: "0.0.0.0",
      port: 5512,
      strictPort: true, // 设为TRUE时若端口被占用会直接退出,FALSE会尝试下一个可用端口
      open: true, // 自动打开浏览器;当此值为字符串时,会被用作 URL 的路径名
    },
  };
});

tsconfig.json配置:

 "compilerOptions": {
    "baseUrl": ".", // 配置baseUrl后,paths解析时会在每个路径前加上baseUrl
    "paths": {
      "@/*": ["src/*"] // 相当于 baseUrl + @/pages === baseUrl + src/pages
    }
  }

只有tsconfig和vite.config都配置过别名才会生效,并且目前发现只在src文件夹下生效,src外的文件夹用别名不生效,原因尚且不明

四、ts全局类型配置

        当希望定义一个全局类型在别的页面也可以使用,需要创建以.d.ts结尾的声明文件;一般来说,ts 会解析项目中所有的 *.ts 文件,当然也包含以 .d.ts 结尾的文件。所以当我们将 xx.d.ts 放到项目中时,其他所有 *.ts 文件就都可以获得这个声明文件中的类型定义了。