使用 vite构建一个React项目

使用vite生成react项目

使用官方提供的命令

yarn create @vitejs/app
复制代码

然后根据你的需要进行选择,我们这里选择React-TS模板

这时候仅仅是支持React语法的,我们还需要其他的配置一起来完成React项目的搭建

TypeScript

在用脚手架生成React项目的时候,是有一个React-TS版本的选择的,建议大家直接选择React-TS版本,这样你可以直接跳过这部分内容。

如果你选择的是React版本,那么如果配置请看下面(没必要,直接选择TS版本呗)

Vite这里自己是支持Typescript语法的,但是它只编译,不校验。意思就是它只是把TS语法编译成JS,能够在浏览器中运行,但是它不会去做TS类型的校验,即使你定义的类型有错误,但是也能是通过正常的编译,如果我们想对TS语法进行校验,可以使用tsc --noEmit命令来进行校验

// test.ts

interface A {
    name:string
}

export const a:A={
    name:'fishfan',
    age:'18'
}

复制代码

上面代码明显是存在TS语法错误的,你能够在编辑器上看到错误(VScode自带的错误提示),但是浏览器仍然能够正常运行。

我们需要安装typescript

yarn add typescript @types/react @types/react-dom -D
复制代码

然后在package.json中修改打包命令

  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "serve": "vite preview"
  },
复制代码

在根目录建立tsconfig.json

{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": false,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve"
  },
  "include": ["./src"]
}

复制代码

这样就会在打包的时候,对错误进行提示

样式

Vite支持 CSS variable 和postCSS

关于css cariable 可以查看该链接

安装相关插件

yarn add  postcss-preset-env autoprefixer  -D   
复制代码

Vie的内部是有Postcss,如果我们想使用postcss的其他plugin的话,在根目录新建postcss.config.js配置如下,情况视项目而定。

module.exports = {
  plugins: [
    require('autoprefixer'),
    require('postcss-preset-env'),
  ],
};
复制代码
autoprefixer

这个就不用多说了,必装插件之一。方便的写规范的css,它会为你提供非常完整的hack兼容方案的。当然这里需要了解一下的是,它的大部分兼容数据来源Can I Use,另外一个稍微需要了解的插件配置参数就是browsers,不过一般我们都是在package.json中配置浏览器版本相关信息。

package.json内增加如下示例,这样其他插件也能够从中获取到项目将要兼容的版本

"browserslist": [
  "> 1%", // 全球浏览器使用率大于1%。
  "last 2 versions"  //  每个浏览器中最新的两个版本。
]
复制代码
postcss-preset-env

postcss-preset-env是帮postcss找到package.json中的browserlist里面的配置,通过配置加载指定的css兼容性样式

css Module

建立的css文件名称为 [name].module.css 就会被识别的css module,如果你的css文件名称不是这么定义的,你是无法使用的css module的

如果验证?建立一个css文件名称为 app.module.css

// app.module.css
.text {
  color: red;
}

复制代码
// app.jsx

import { useState } from 'react';
import styles from './app.module.css';

function App() {
  return <div className={styles.text}>hello fishfan</div>;
}

export default App;

复制代码

你再将module字段去除,你会发现css样式不起作用

less sass 等 css预处理工具

如果你要是使用哪个你就安装哪个预处理器即可 我们拿less为例

yarn add less -D
复制代码

安装之后你就可以使用less,无须其他配置。

eslint & prettier

eslint是用来规范代码的书写格式,团队项目必备! pritter 自动帮我们格式化的

eslint

在根目录建立.eslintrc.js文件,eslint的规则可以由我们自己来书写,关于如何配置可以 点击此处

这里就按照我的package.json来安装就可以

packag.json配置如下

{
  "name": "vite",
  "version": "0.0.0",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "serve": "vite preview",
    "lint:fix": "eslint ./src --ext .jsx,.js,.ts,.tsx --quiet --fix --ignore-path ./.gitignore",
    "lint:format": "prettier  --loglevel warn --write \"./**/*.{js,jsx,ts,tsx,css,md,json}\" ",
    "lint": "yarn lint:format && yarn lint:fix ",
    "type-check": "tsc"
  },
  "dependencies": {
    "react": "^17.0.0",
    "react-dom": "^17.0.0"
  },
  "devDependencies": {
    "@types/react": "^17.0.0",
    "@types/react-dom": "^17.0.0",
    "@typescript-eslint/eslint-plugin": "^4.28.2",
    "@typescript-eslint/parser": "^4.28.2",
    "@vitejs/plugin-react": "^1.0.0",
    "eslint": "^7.30.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-html": "^6.2.0",
    "eslint-plugin-import": "^2.23.4",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-prettier": "^3.4.0",
    "eslint-plugin-promise": "^5.1.1",
    "eslint-plugin-react": "^7.24.0",
    "eslint-plugin-simple-import-sort": "^7.0.0",
    "pre-commit": "^1.2.2",
    "prettier": "^2.3.2",
    "typescript": "^4.3.2",
    "vite": "^2.6.4"
  }
}

复制代码

创建eslint规则文件.eslintrc.js

module.exports = {
  root: true,
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 2020,
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true,
    },
  },
  settings: {
    react: {
      version: 'detect',
    },
  },
  env: {
    browser: true,
    amd: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:jsx-a11y/recommended',
    'plugin:prettier/recommended', // Make sure this is always the last element in the array.
  ],
  plugins: ['simple-import-sort', 'prettier'],
  rules: {
    'prettier/prettier': ['error', {}, { usePrettierrc: true }],
    'react/react-in-jsx-scope': 'off',
    'jsx-a11y/accessible-emoji': 'off',
    'react/prop-types': 'off',
    '@typescript-eslint/explicit-function-return-type': 'off',
    'simple-import-sort/imports': 'error',
    'simple-import-sort/exports': 'error',
    'jsx-a11y/anchor-is-valid': [
      'error',
      {
        components: ['Link'],
        specialLink: ['hrefLeft', 'hrefRight'],
        aspects: ['invalidHref', 'preferButton'],
      },
    ],
  },
};

复制代码

创建不需要eslint检测的文件.eslintignore

node_modules
.DS_Store
dist
dist-ssr
*.local
node_modules/*
复制代码

按照规则我们会发现我们的许多代码都是不符合规范的,如果去修改需要手动的一个一个去修改(或者在commit的时候,使用eslint一键修复),这样很麻烦,我们想实现在保存的时候,能够自动地修复。

这时候就需要我们的prettier出场

prettier

关于prettier详细介绍可以 点击此处

在VScode 我们首先要安装Prettier插件

在根目录插件.prettierrc.js文件 内容如下,可以根据自己的需求来配置规则

module.exports = {
  semi: true,
  trailingComma: 'all',
  singleQuote: true,
  printWidth: 90,
  tabWidth: 2,
  jsxBracketSameLine: true,
  endOfLine: 'auto',
};

复制代码

同样创建忽略修复的文件.prettierignore

node_modules
.DS_Store
dist
dist-ssr
*.local
node_modules/*
复制代码

打开VScode的自动保存配置

第一步打开设置搜索format on save 如图进行设置

6.png

第二步搜索**formatter ** 选择prettier

7.png

在代码提交之前,进行代码规则检查能够确保进入git仓库的代码都是符合规范的,但是整个项目运行lint速度会很慢,lint-staged能够让lint只检测暂存区的文件,所以速度很快

安装husky和lint-staged

yarn add husky lint-staged -D
复制代码

package.json添加如下配置

  "husky":{
    "hooks":{
      "pre-commit":"lint-staged"
    }
  },
  "lint-staged":{
    "*.js":"eslint --fix",
    "*.ts":"eslint --fix"
  },
复制代码

当文件变化,我们git commit它们,pre-commit钩子会启动,执行lint-staged命令.

resolve

alias

路径别名 和webpack中的alias功能一样,当项目比较复杂的时候,如果在深层的文件想引入最外层的文件 例如会出现如下情况,我们可以将src设置为跟目录,用@符来标识

import untils from '../../../../util' // 未使用别名

import untils from '@/util' // 使用别名后
复制代码

extensions

使用extensions可以忽略导入时候的扩展名,例如

import App from './app.jsx    // 未使用extensions

import App from './app    // 使用extensions
复制代码

修改vite.config.ts的文件

 // vite.config.ts
 
 
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'],
    alias: {
      '@': '/src',
    },
  },
})

复制代码

server

关于配置中server需要关注的是proxy,请求代理,如果我们没有设置proxy,那么我们发送请求就会出现跨域的情况。

 server: {
    proxy: {
      '/api': {
        target: 'https://www.xxx.xxx',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      },
    }
  }
复制代码

在vite.config.js这么配置,那么你的请求url前缀都是以**/api**开头的话,就会被转发到www.xxx.xxx中。

至此关于React项目基本的搭建已经完毕,下面介绍的是如何在Vite搭建的React项目中使用React-route和Antd

下面内容参照该文章 juejin.cn/post/693867…

路由

首选安装 react-router-dom

yarn add react-router-dom -D   // 这么安装是react-router-dom的最新版本 我的版本6.0.2
复制代码

react-router-dom的最新版本(6x之后)不提供Switch组件而是使用Routes,关于react-router-dom 5x版本和6x版本的差异请点击下方链接查看

链接1

链接2

链接3

在src文件下建立Home和About文件夹,并创建对应的文件

/src/Home/index.tsx

import React from 'react'

export default function index() {
  return (
    <div>
      Home
    </div>
  )
}

复制代码
/src/About/index.tsx

import React from 'react'

export default function index() {
  return (
    <div>
      About
    </div>
  )
}

复制代码

根目录创建route.tsx文件

这里我需要解释下为什么route文件是tsx而不是ts文件,主要是内部需要直接使用组件 ,之前我是使用导出函数,然后在Route里面执行函数的方式来,发现Vite不在热更新,很神奇,感觉这是Vite与最新的React-route-dom不兼容的问题,我补充下有问题代码的写法 如下:

// route.tsx
import Home from '../src/Home'
import About from '../src/About'

const routes = [
  {
    path: "/home",
    component: Home
  },
  {
    path: "/about",
    component: About
  }
];

export default routes



// App.tsx
import React from 'react'
import {  Route, Routes } from "react-router-dom";
import routes from './route'
import './App.css'

function App() {
  return (
    <div className="App">
        <Routes>
          {
            routes.map(item => {
              return <Route path={item.path} key={item.path} element={item.component()}/>
            })
          }
        </Routes>
    </div>
    
  )
}

export default App

这是使用之后Vite不在热更新的写法!!!


复制代码

没有问题的写法

// route.tsx
import Home from '../src/Home'
import About from '../src/About'

const routes = [
  {
    path: "/home",
    component: <Home/>
  },
  {
    path: "/about",
    component: <About/>
  }
];

export default routes

复制代码

修改App.tsx文件

import React from 'react'
import {  Route, Routes } from "react-router-dom";
import routes from './route'
import './App.css'

function App() {
  return (
    <div className="App">
        <Routes>
          {
            routes.map(item => {
              return <Route path={item.path} key={item.path} element={item.component}/>
            })
          }
        </Routes>
    </div>
    
  )
}

export default App

复制代码

修改main.tsx文件

import React from 'react'
import ReactDOM from 'react-dom'
import {BrowserRouter} from 'react-router-dom'
import './index.css'
import App from './App'

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById('root')
)

复制代码

分别访问 http://localhost:3000/homehttp://localhost:3000/about 会看到自己路由生效

使用Antd

安装antd和 @ant-design/icons ,antd 4x版本之后图标库就和antd本身区分开了,需要单独安装

yarn add antd @ant-design/icons
复制代码

在App.tsx文件引入antd

import React from 'react'
import { Route, Routes} from "react-router-dom";
import routes from './route'
import { Button } from 'antd'
import './App.css'

function App() {
  return (
    <div className="App">
      <Button type="primary">fishfan</Button>
        <Routes>
          {
            routes.map(item => {
              return   <Route path={item.path} key={item.path} element={item.component}/>
            })
          }
        </Routes>
    </div>
  )
}

export default App

复制代码

你会发现

1.png

那是因为我们没有引入antd 的样式,在main.tsx引入antd的样式

// main.tsx
import 'antd/dist/antd.css'
复制代码

2.png 样式生效了!!! 但是运行打包命令

yarn build
复制代码

我们来看下打包后的css体积,有500多KB,很明显样式没有实现按需加载。

3.png

antd样式实现按需加载

请注意我们这里使用的是less,如果你是使用css,下方配置对应的也需要修改

安装vite-plugin-imp

yarn add vite-plugin-imp -D
复制代码

修改vite.config.js

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import vitePluginImp from 'vite-plugin-imp'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    vitePluginImp({
      libList: [
        {
          libName: "antd",
          style: (name) => `antd/lib/${name}/style/index.less`, // 这里是less,没安装less,就使用css(css使用全局样式无法生效)
        },
      ],
    })
  ],
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true,
      }
    }
  },
})

复制代码

删除main.tsx 引入antd样式的代码

import 'antd/dist/antd.css'   删除
复制代码

再运行打包命令发现css的体积减小到40kb左右,体积大幅减少。

4.png

如何修改antd的全局样式

修改vite.config.js中的css配置,添加modifyVars对象,对象的变量就是antd全局的变量值

  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true,
        modifyVars:{
            'primary-color': '#ff704c',
            'link-color': '#ff704c',
            'border-radius-base': '4px',
        }
      }
    }
  },
复制代码

5.png

我们会发现设置的全局主题颜色发生了变化,说明我们的配置生效了

结束结束

项目地址: github.com/wuqiren/fis…

猜你喜欢

转载自juejin.im/post/7034499668134494245