Vite+Vue+Typescript+Less+Pinia+Vue Router+Vue Test Utils+Axios
初始化项目
目前已经有非常成熟的脚手架一键搭建,Vite社区甚至还有各位开发大神自我搭建的模板可以使用,有很多各种功能的第三方库,后期可用于新手学习
$ npm create vite template-vue-ts --template vue-ts
√ Select a framework: » Vue
√ Select a variant: » Customize with create-vue ↗
Need to install the following packages:
create-vue@3.10.2
Ok to proceed? (y) y
Vue.js - The Progressive JavaScript Framework
√ 是否使用 TypeScript 语法? ... 否 / 是 是
√ 是否启用 JSX 支持? ... 否 / 是 否
√ 是否引入 Vue Router 进行单页面应用开发? ... 否 / 是 是
√ 是否引入 Pinia 用于状态管理? ... 否 / 是 是
√ 是否引入 Vitest 用于单元测试? ... 否 / 是 是
√ 是否要引入一款端到端(End to End)测试工具? » 不需要 否
√ 是否引入 ESLint 用于代码质量检测? ... 否 / 是 是
√ 是否引入 Prettier 用于代码格式化? ... 否 / 是 是
√ 是否引入 Vue DevTools 7 扩展用于调试? (试验阶段) ... 否 / 是
正在初始化项目 D:\Project\template-vue-ts\template-vue-ts...
项目初始化完成,可执行以下命令:
cd template-vue-ts
npm install
npm run format
npm run dev
Less
安装
npm install less -D
Vite预处理器配置
// vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueDevTools from 'vite-plugin-vue-devtools'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), VueDevTools()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
css: {
preprocessorOptions: {
// 配置Less预处理器
less: {
math: 'always'
}
}
}
})
Axios封装
安装
npm install axios
封装
// src/utils/https.ts
import axios, { AxiosError, type AxiosInstance, type AxiosRequestConfig } from 'axios'
// Axios实例
const instance: AxiosInstance = axios.create({
baseURL: '/api',
timeout: 10000, // 超时时间 10秒
withCredentials: true
})
// 请求拦截器
instance.interceptors.request.use((config) => {
// 请求前的操作
return config
})
// 响应拦截器
instance.interceptors.response.use((response) => {
// 响应前的操作
return response
})
type iHttpType = 'GET' | 'POST' | 'PUT' | 'DELETE'
// 封装 Axios T 传参类型 R 返回值类型
export const http = <T, R>(
method: iHttpType,
url: string,
params?: T,
config?: AxiosRequestConfig
): Promise<R> => {
return new Promise((resolve, reject) => {
switch (method) {
case 'GET':
instance
.get<R>(url, { ...config, params })
.then((res) => {
resolve(res.data)
})
.catch((err: AxiosError) => {
reject(err)
})
break
case 'POST':
instance
.post<R>(url, params, { headers: { 'Content-Type': 'application/json' }, ...config })
.then((res) => {
resolve(res.data)
})
.catch((err: AxiosError) => {
reject(err)
})
break
case 'PUT':
instance
.put<R>(url, params, { headers: { 'Content-Type': 'application/json' }, ...config })
.then((res) => {
resolve(res.data)
})
.catch((err: AxiosError) => {
reject(err)
})
break
case 'DELETE':
instance
.delete<R>(url, { ...config, params })
.then((res) => {
resolve(res.data)
})
.catch((err: AxiosError) => {
reject(err)
})
break
}
})
}
vite-plugin-vue-setup-extend(可选)
在Setup语法糖中可直接设置组件name
安装
npm install vite-plugin-vue-setup-extend -D
配置
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueDevTools from 'vite-plugin-vue-devtools'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
export default defineConfig({
plugins: [vue(), VueDevTools(), VueSetupExtend()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
使用
<template>
<div>test</div>
</template>
<script lang="ts" setup name="自定义name">
import { onMounted } from 'vue'
onMounted(() => {
console.log('render')
})
</script>
Vite配置项优化
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueDevTools from 'vite-plugin-vue-devtools'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
// import { readFileSync } from 'node:fs'
// https://vitejs.dev/config/
export default defineConfig({
server: {
// dev环境端口号
port: 8000,
// dev环境SSL证书
// https: {
// key: readFileSync('证书密钥路径'),
// cert: readFileSync('证书文件路径')
// }
// 反向代理
proxy: {
'/api': {
target: '目的地址',
changeOrigin: true,
rewrite: (path) => path, // 地址转换
headers: {} // 转发请求头
}
}
},
plugins: [vue(), VueDevTools(), VueSetupExtend()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
css: {
preprocessorOptions: {
less: {
math: 'always'
}
}
},
build: {
target: 'modules', //浏览器兼容性modules|esnext
sourcemap: false, //构建后是否生成source map文件
minify: 'terser', // 混淆器,terser构建后文件体积更小
// outDir: envConfig.VITE_OUTPUT_DIR, //指定输出文件包名
outDir: 'dist',
assetsDir: 'assets', // 指定生成静态资源的存放路径
chunkSizeWarningLimit: 1500, //警报门槛,限制大文件大小B为单位
assetsInlineLimit: 4096, //小于此阈值的导入或引用资源将内联为base64编码,以避免额外的http请求,设置为0可以完全禁用此项
// 清除console和debugger(minify: 'terser',)设置后这个terserOptions才有用
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
},
rollupOptions: {
output: {
//自动分割包名输出 chunkSizeWarningLimit 配置大小
chunkFileNames: 'js/[name]-[hash].js', //入口文件名
entryFileNames: 'js/[name]-[hash].js', //出口文件名位置
assetFileNames: 'static/[ext]/[name]-[hash].[ext]', //静态文件名位置
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString()
}
}
}
}
}
})
评论区