手动搭建VITE + REACT

自22年离开老东家,就没有试用过react了,目前也不知道react的最新版本更新到哪一个版本了,有那些新特性了。刚好最近被裁员,也有空看看react相关技术栈了,就浅浅的动手搭一下react的项目模板试试,了解一下react的新版和新特性。

1、准备工作

  1. 电脑上有JavaScript运行环境,如node,react 19 建议使用node 20 以上版本。
  2. 对应包管理器,如npm。

2、安装必要的包

基础包

javascript 复制代码
react  
react-dom  
react-router-dom // web项目使用该路由包
vite // 编译器
babel-plugin-react-compiler // 编译器
rollup-plugin-terser // 代码压缩工具
sass // 编译scss|sass

typeScript支持包

javascript 复制代码
@types/react // reat typeScript 类型支持
@types/react-dom // reactDom typeScript 类型支持

eslint支持包

javascript 复制代码
eslint
eslint-plugin-import // import 语法支持
eslint-plugin-react // react 语法插件
eslint-plugin-react-hooks // react hooks 语法校验支持 
eslint-plugin-react-compiler // eslint 编译器支持
typescript-eslint // eslint typescript 语法支持
@eslint/js // js语法支持包
globals // node 全局变量包

格式化工具

javascript 复制代码
prettier
eslint-plugin-prettier // eslint-prettier 支持包
eslint-config-prettier // eslint 与 prettier 规则冲突解决包

3、相关配置

vite 配置

typescrit 复制代码
import react from "@vitejs/plugin-react";
import { terser } from "rollup-plugin-terser";
import { defineConfig } from "vite";

const isProd = process.env.NODE_ENV === "production";

export default defineConfig({
  plugins: [
    react(),
    // @ts-ignore
    isProd && terser(), // 仅在生产环境使用压缩
  ],
  build: {
    outDir: "./dist",
    minify: isProd, // 生产环境使用压缩
    sourcemap: !isProd,
    rollupOptions: {
      output: {
        manualChunks: {
          // 第三方依赖库打包到一个文件
          react: ["react-dom", "react"],
        },
      },
    },
  },
  optimizeDeps: {
    include: ["react", "react-dom"],
  },
  server: { port: 3000, open: true },
});

eslint 配置

eslint 8 版本配置,为以下格式,支持配置文件格式参考文档

typescript 复制代码
export default {
  root: true,
  extends: ["eslint:recommended", "plugin:react/recommended"],
  parser: "@typescript-eslint/parser",
  parserOptions: {
    project: "./tsconfig.json",
    sourceType: "module",
    ecmaVersion: 2020,
    ecmaFeatures: {
      jsx: true,
    },
  },
  plugins: ["@typescript-eslint", "prettier"],
  env: {
    browser: true,
    node: true,
  },
  rules: {
    "prettier/prettier": "error",
  },
};

eslint 9 以后,不在支持.eslintrc,json,yaml,yml格式的配置文件了,后续使用的文件名为 eslint.config.js|mjs|cjs|ts|mts|cts 文件。参考文档

typescript 复制代码
import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginReact from "eslint-plugin-react";

/** @type {import('eslint').Linter.Config[]} */
export default [
  { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"] },
  { settings: { react: { version: "detect" } } },
  { languageOptions: { globals: { ...globals.browser, ...globals.node } } },
  pluginJs.configs.recommended,
  ...tseslint.configs.recommended,
  pluginReact.configs.flat.recommended,
  {
    rules: {
      "@typescript-eslint/no-explicit-any": "off",
      "@typescript-eslint/ban-ts-comment": "off",
      /**
       * 不检查以下划线开头的 未使用的变量
       * 包含了参数变量,解构变量,catch中的参数变量
       */
      "@typescript-eslint/no-unused-vars": [
        "error",
        {
          argsIgnorePattern: "^_",
          caughtErrorsIgnorePattern: "^_",
          destructuredArrayIgnorePattern: "^_",
        },
      ],
    },
    ignores: [],
  },
];

prettier 配置

typescript 复制代码
printWidth: 100, // 每行代码长度(默认80)
tabWidth: 2, // 每个tab相当于多少个空格(默认2)ab进行缩进(默认false)
useTabs: false, // 是否使用tab
semi: false, // 声明结尾使用分号(默认true)
vueIndentScriptAndStyle: false,
singleQuote: true, // 使用单引号(默认false)
quoteProps: "as-needed",
bracketSpacing: true, // 对象字面量的大括号间使用空格(默认true)
trailingComma: "none", // 多行使用拖尾逗号(默认none)
jsxSingleQuote: false,
// 箭头函数参数括号 默认avoid 可选 avoid| always
// avoid 能省略括号的时候就省略 例如x => x
// always 总是有括号
arrowParens: "always",
insertPragma: false,
requirePragma: false,
proseWrap: "never",
htmlWhitespaceSensitivity: "strict",
endOfLine: "auto",
rangeStart: 0

入口文件

入口文件,是配置在package.json里的main字段,即:打包入口文件。

tsx 复制代码
// 导入必要对象
import React from "react"
import ReactDOM from "react-dom/client" // DOM处理客户端渲染包
import App from "@/App"
import { BrowserRouter } from "react-router-dom" // 路由

ReactDOM.createRoot(document.getRElementById('app') as HTMLElement).render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
)

路由配置

路由配置文件。

tsx 复制代码
import Home from '@/pages/home/index'

import type { RouteObject } from 'react-router-dom'
import { Navigate } from 'react-router-dom'

// const Entry = lazy(() => import('@/pages/entry')) // 路由懒加载使用lazy

const routes: RouteObject[] = [
  { path: '/', element: <Navigate to={'/index'} /> },
  {
    path: '/index',
    element: <Home />
  }
]
export default routes

App.tsx 文件

在app.tsx文件里引入头尾部以及公共样式,路由渲染相关内容。

javascript 复制代码
import AppHeader from '@/components/header'
import AppFooter from '@/components/footer'
import routes from '@/router'
import { useRoutes } from 'react-router-dom'
import '@/style/common.scss'

const App = () => {
  console.log('App is running!')
  const RoutePage = useRoutes(routes)
  return (
    <div className={'app'}>
      <AppHeader />
      <div className="main-container">{RoutePage}</div>
      <AppFooter />
    </div>
  )
}

export default App

项目基本结构

相关推荐
Nan_Shu_61417 分钟前
学习: Threejs (2)
前端·javascript·学习
G_G#25 分钟前
纯前端js插件实现同一浏览器控制只允许打开一个标签,处理session变更问题
前端·javascript·浏览器标签页通信·只允许一个标签页
@大迁世界40 分钟前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路1 小时前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug1 小时前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu121381 小时前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中1 小时前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路1 小时前
GDAL 实现矢量合并
前端
hxjhnct1 小时前
React useContext的缺陷
前端·react.js·前端框架
前端 贾公子2 小时前
从入门到实践:前端 Monorepo 工程化实战(4)
前端