vite版本版本:vite:2.7.2
react版本:react:17.0.2
代码仓库地址:gitee地址哦
今天是2022年的第一天上班,想着 摸会鱼吧 学习新东西,也好久没弄vite和react了,干脆一不二不休,一起整一个
1、创建项目
命令
# npm 6.x
npm init vite@latest my-vue-app --template vue
# npm 7+, 需要额外的双横线:
npm init vite@latest my-vue-app -- --template vue
# yarn
yarn create vite my-vue-app --template vue
# pnpm
pnpm create vite my-vue-app -- --template vue
完成之后,进入你的项目目录,执行下面命令即可,然后界面差不多就是这样的
cd my-project
npm install
npm run dev
看下基本的文件结构
2、加入react路由
我安装的是最新版的react路由,写法和5.x的有点不同,更多详情可以去官网查看
react-router v6官方文档
1、首先安装react路由的包:npm i react-router-dom -S
2、src目录下新建pages用于存放页面组件,components用于存放业务和基本组件;在pages目录中新建Home和About两个页面,然后随便写点东西
3、这里新建页面不能是.js后缀名,必须是.jsx不然vite会报错
// home/index.jsx
import React from 'react'
export default function Index() {
return <div>
主页面111
</div>
}
// about/index.jsx
import React from 'react'
export default function About() {
return <div>
这是About页面
</div>
}
然后新建src/router/index.js
来配置一下基本的路由
import Home from '../pages/home'
import About from '../pages/about'
const routes = [
{
path: '/',
component: Home
},
{
path: '/about',
component: About
}
]
export default routes
到我们的App.jsx 引入路由,然后我们到浏览器里面看下效果
// App.jsx代码
import React from 'react'
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom'
import routes from './router'
function App() {
return <Router>
<Routes>
{
routes.map(item => {
const Component = item.component
return <Route exact key={item.path} path={item.path} element={<Component />} />
})
}
</Routes>
</Router>
}
export default App
3、引入antd
首先先来下载下来:npm install antd --save
;随后在main.jsx中全量引入样式,先看看能不能成功
main.jsx代码
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import 'antd/dist/antd.css'
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
)
看到页面中也是可以正常显示的
home/index.jsx
代码
import React from 'react'
import {Button} from 'antd'
export default function Home() {
return (
<div>
主页面111
<Button type="danger">按钮11</Button>
</div>
)
}
4、优化antd体积
到这里我想先不进行下去了,来做个优化。首先我们是全量引入antd的样式,先来打包看下怎么样。终端执行npm run build
,
你可以在终端中查看每个文件的体积,也可以在资源管理器查看,我们到管理器看一下
好家伙,就那么点东西直接给我干到773kb了!!!真是不让我活了
行吧,既然已经这样了,那就来优化吧,毕竟是自己写的代码,要负责哦~~
1、首先antd官网里面并没有说明怎么在vite里面按需引入antd组件,so只能去vite官方找找
2、 愣眼一分钟好像vite官方也没有…,等等好像下面还有一个社区插件,点进去看看
3、soga soga ,这不是一大推吗,我就在那慢慢找,果不其然,还真找到了2个
社区插件里面有很多,这里就不截图了,感兴趣的可以直接:点此进入
上面那个style-import就不需要,那是引入样式,和我们想要的不一致
咱英文也不好,翻译看看几个意思。原来如此啊~~,第二个就是符合我们预期的,那就快来npm吧:npm i vite-plugin-imp -D
这里把这个插件的github地址也给大家放上,方便查阅:vite-plugin-imp—github地址
安装完成之后呢,根据文档上的地址在vite.coonfig.js中加入对应的配置代码
因为配置了javascriptEnabled
为 true,所以也要记得安装less哦:npm i less -D
import {defineConfig} from 'vite'
import react from '@vitejs/plugin-react'
import VitePluginImp from 'vite-plugin-imp'
export default defineConfig({
base: base.cdn,
plugins: [
react(),
VitePluginImp({
libList: [
{
libName: 'antd',
style(name) {
// use less
return `antd/es/${name}/style/index.js`
}
},
]
})
],
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
}
}
},
})
接下来我们把main.jsx中全量引入的代码去掉。重新npm run build
一下看看。surprised md fuck !!!!!真香啊,
产品再也不用担心我的体积包太大了
**
5、自定义antd主题色
**
为什么要做这一步呢,有些项目中,UI的设计(瞎画)可能主题色并不是antd默认的,但是呢又不想和UI在那撕皮让他就用antd的,毕竟我们是有追求的程序员。webpack中我们直接在modifyVars一行代码搞定,然后下班关机走人。但是!!!这是vite
1、根目录下新建`config/variables.less`
说一下为什么新建一个less文件来呢,直接在modifyVars不好吗,是为了后期万一改一些margin、圆角、文字大小做准备哦
```bash
// 自定义覆盖 =============================================================
@primary-color: blue; // 全局主色
// 下面你可以各种写一些覆盖的样式,先随便搞个蓝色的主题色
2、安装less-vars-to-js (如果你只是单纯的修改主题色,那么这个也不用安装),配置vite.config.js
less-vars-to-js 是将 less 样式转化为 json 键值对的形式,你也可以直接在 modifyVars 属性后写 json 键值对,都一样
import path from 'path'
import fs from 'fs'
import lessToJS from 'less-vars-to-js'
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, './config/variables.less'), 'utf8')
)
...
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
modifyVars: themeVariables
}
}
}
修改home/index.jsx
中button的属性为primary
一下我们重新dev一下,到浏览器看看,哎呦喂perfect,产品再也不用担心我和UI撕皮了
6、配置环境变量
官方文档上说可以通过.env方式,即之前那种新建开发、生成环境下的env文件
不过我们也可以通过脚本的方式来配置,先修改一下package.json
–mode 后代表的是各个环境对应的环境变量值,这里为什么一定要用 --mode 呢?官方定的
来打印下看看,最后一个参数,便是我们设置好的环境变量,只需修改下vite配置获取到就好
/*
* @Author: 徐建辰
* @Date: 2022-01-04 08:44:49
* @LastEditTime: 2022-01-04 10:00:45
* @LastEditors: Please set LastEditors
* @Description: vite基本配置,请勿修改
*/
import {defineConfig} from 'vite'
import react from '@vitejs/plugin-react'
import VitePluginImp from 'vite-plugin-imp'
import path from 'path'
import fs from 'fs'
import lessToJS from 'less-vars-to-js'
import config from './config'
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, './config/variables.less'), 'utf8')
)
// 获取环境变量
const env = process.argv[process.argv.length - 1]
const base = config[env]
console.log('环境变量----------', process.argv)
// https://vitejs.dev/config/
export default defineConfig({
base: base.cdn,
plugins: [
react(),
VitePluginImp({
libList: [
{
libName: 'antd',
style(name) {
// use less
return `antd/es/${name}/style/index.js`
}
},
]
})
],
/* less全局变量 */
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
modifyVars: themeVariables
}
}
},
})
config文件夹下新建index.js,写入配置代码,执行打包命令看看效果
export default {、
development: {
cdn: './',
baseUrl: '/api'
},
release: {
cdn: 'xxxxxxx.com/xxxx/yyyyy',
baseUrl: '//www.xxx.com/yyyyy'
}
}
那么问题来了,怎么在jsx页面或者其他js文件里面获取到环境变量呢?答案是通过import.meta.env
,不要问我为什么,因为是官方文档说的
// home/index.jsx代码
import React from 'react'
import {Button} from 'antd'
console.log('这是获取后的环境变量---------', import.meta.env)
export default function Home() {
return (
<div>
主页面111
<Button type="primary">按钮11</Button>
</div>
)
}
7、配置别名和代理
/* 别名 */
resolve: {
alias: {
'~': path.resolve(__dirname, './'), // 根路径
'@': path.resolve(__dirname, 'src') // src 路径
}
},
/* 代理 */
server: {
port: 3030, // 开发环境启动的端口
proxy: {
'/api': {
target: 'http://xxxxx/yyy/zzz',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '') // 将 /api 重写为空
}
}
}
8、统一封装axios
1、安装axios、qs:npm i axios qs -S
2、service/request.js
下进行统一请求封装
import axios from 'axios'
import {message} from 'antd'
import config from '~/config'
const MODE = import.meta.env.MODE
const instance = axios.create({
baseURL: config[MODE].baseUrl,
timeout: 7000
})
// 请求拦截
instance.interceptors.request.use(config => {
const token = '你的token'
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
}, error => {
return Promise.reject(error)
})
// 响应拦截
instance.interceptors.response.use(res => {
const {success, message, data} = res.data
if (success) {
return data
} else {
message.error(message)
return Promise.reject(new Error(message))
}
}, err => {
// token过期,其实也可以在成功的回调中处理
if (err.response && err.response.data && err.response.data.code === 401) {
// do something...
}
message.error(err.message)
return Promise.reject(err)
})
export default instance
使用(记得在对应文件引入)
request({
url: 'xxxxxx',
method: 'post', // get 则不用写
params: {},
headers: {},
withCredentials: 'true or false 默认false',
}).then(res => {
console.log(res)
}).catch(err => {
console.log(res)
})
9、结尾
至于eslint啊、ts啊、pitter啊,有时间就加上,代码已上传至仓库,请自行查看。master分支默认为vite-vue