基于vite+vue3的中台前端搭建
1.创建
1.1 vite
# 环境:
# Node 20.x
# Vite 6.x
# Typescript 5.x
pnpm create vite
# Project name: admin-template
# Select a framework: Vue
# Select a variant: TypeScript
cd admin-template
pnpm install # 安装依赖
pnpm dev # 启动项目
1.2 其它必要依赖
项目初步创建后package.json中只有vue、vite、vue-tsc、typescript、@vitejs/plugin-vue这几个依赖,所以要安装以下依赖项:
# 1、必要依赖项 vue-router、axios、vue-i18n、pinia、@vitejs/plugin-vue-jsx、less或sass
# 2、组件:element-plus、@element-plus/icons-vue
# 3、辅助:nprogress、mitt、radashi、dayjs、@vueuse/core、@types/node、unplugin-auto-import、unplugin-vue-components
# 4、部分依赖需要另安装类型声明包:@types/nprogress、@types/mockjs
pnpm add vue-router axios vue-i18n pinia @vitejs/plugin-vue-jsx sass
pnpm add element-plus @element-plus/icons-vue
pnpm add -D unplugin-auto-import unplugin-vue-components
pnpm add nprogress mitt radashi dayjs @vueuse/core
pnpm add -D @types/nprogress @types/mockjs @types/node
将 lodash 替换成 radash 或 radashi:
radashi 和 radash 是同一项目的不同分支,主要区别在于维护状态和目标定位:.
-
radash 侧重替代lodash的通用工具函数需求,支持TS开发,适合需要完整工具函数库的开发者。 radashi是radash的活跃维护分支,持续更新并优化工具函数,强调轻量化、类型安全和无依赖特性。 推荐给追求轻量化、无依赖且注重代码维护性的项目。(二者其中某些函数的使用方式存在差异,使用时请相应参考文档: Radash、Radashi)
2 vite.config.ts基础配置
2.1 配置路径别名alias
// vite.config.ts
import { defineConfig } from 'vite';
import { resolve } from 'path'; // 需要安装 @types/node
export default defineConfig({
resolve: {
alias: {
"~": resolve(process.cwd()),
"@": resolve(__dirname, 'src'),
'@ts': resolve(__dirname, 'src/types'),
'@utils': resolve(__dirname, 'src/utils'),
'@comps': resolve(__dirname, 'src/components')
}
}
})
然后需要在tsconfig.json中的compilerOptions配置baseUrl、paths;
{
"compilerOptions": {
/* alias */
"baseUrl": "./",
"paths": {
"~/*": ["./*"],
"@/*": ["src/*"],
"@ts/*": ["src/types/*"],
"@utils/*": ["src/utils/*"],
"@comps/*": ["src/components/*"],
}
}
}
2.2 提供全局 less/scss 变量
-
less:pnpm add -D less// vite.config.ts export default defineConfig({ css: { preprocessorOptions:{ less:{ additionalData: '@import "@/styles/variables/index.less";', javascriptEnabled: true, } } }, }) -
sass:pnpm add -D sass// vite.config.ts export default defineConfig({ css: { preprocessorOptions:{ scss:{ additionalData: '@use "@/styles/variables/index.scss" as *;' } } }, })
2.3 定义全局常量替换方式define
定义全局常量替换方式。其中每项在开发环境下会被定义在全局,而在构建时被静态替换。
// config/config/define.ts
import dayjs from 'dayjs';
import pkg from '../../package.json';
/** 项目构建时间 */
const APP_BUILD_TIME = JSON.stringify(dayjs().format('YYYY-MM-DD HH:mm:ss'));
/** 项目信息 */
const { dependencies, devDependencies, name, version } = pkg;
const APP_PKG_INFO = {
dependencies,
devDependencies,
name,
version
};
export const viteDefine = {
APP_BUILD_TIME,
APP_PKG_INFO
}
NOTE:想要获得类型检查以及代码提示: 确保在全局声明文件(比如:global.d.ts)中添加类型声明。
// src/types/dts/global.d.ts
/** 构建时间 */
declare const APP_BUILD_TIME: string;
/** 平台的名称、版本、依赖 */
declare const PKGVersionInfo: {
name: string;
version: string;
}
declare const APP_PKG_INFO: {
name: string;
version: string;
dependencies: PkgVersionInfo[];
devDependencies: PkgVersionInfo[];
}
/**
* .vue 文件中使用
<script lang="ts" setup>
const BUILDTIME = ref(APP_BUILD_TIME);
const APPINFO = ref(APP_PKG_INFO)
</script>
*/
2.4 配置代理 Proxy
Vite代理配置选项:server-proxy
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
const viteEnv = loadEnv(mode, process.cwd()) as unknown as ImportMetaEnv;
return {
server: {
port: viteEnv.VITE_PORT,
open: false,
proxy: {
/** 代理标识符,可根据实际情况自行修改 */
'/api': {
/** 要代理的后端 api 地址 !可以将改地址配置到环境文件中,然后通过viteEnv引用 */
target: 'http://255.255.1.1:8081/',
/** 是否改写 origin。设为 true,则请求 header 中 origin 将会与 target 配置项的域名一致。 */
changeOrigin: true,
/** 重写转发的请求链接, 如果需要 */
rewrite: (url) => url.replace(/^\/api/, ''),
},
},
},
}
})
3 plugins
3.1 按需自动导入 vue
vue、vue-router、pinia都可以通过unplugin-auto-import实现自动导入(只建议设置vue自动导入)。
安装:pnpm add -D unplugin-auto-import;
import AutoImport from 'unplugin-auto-import/vite';
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
return {
plugins: [
vue({
script: {
defineModel: true, // Vite 插件会自动为所有 Vue 组件创建对应的 TypeScript 接口,以增强类型检查的效果
}
}),
AutoImport({
imports: ['vue'],
dts: 'src/types/auto-import.d.ts', // 指定文件生成位置
}),
]
}
})
3.2 使用TSX/JSX
-
依赖:
pnpm add -D @vitejs/plugin-vue-jsx -
使用:
import vueJsx from '@vitejs/plugin-vue-jsx'; export default defineConfig(({ mode }: ConfigEnv): UserConfig => { return { plugins: [ vueJsx() ] } }) -
确保
tsconfig.json中包含以下配置{ "compilerOptions": { "jsx": "preserve", // 主要是这个,使.tsx 中支持 JSX "jsxFactory": "h", "jsxFragmentFactory": "Fragment" } } -
基础示例:
export default defineComponent({ name: "TsxTest", render() { const _envTitle = ref<string>(import.meta.env.VITE_APP_NAME) console.log("_envTitle:", _envTitle.value); const count = ref<number>(0) return ( <> <h1>Tsx_Test: {_envTitle.value}</h1> <p>测试{count.value}</p> </> ) } }) /** * 引入.vue文件一样: import TsxTest from '@comps/TsxTest'; * <template> * <TsxTest /> * </template> */
3.3 可选:按需引入UI框架
-
ElementPlus:https://element-plus.org/zh-CN/guide/design -
naive-ui:https://www.naiveui.com/zh-CN/os-theme/docs/installation -
AntDesignVue:https://www.antdv.com/docs/vue/introduce-cn/
3.4 综合
创建与src同级的文件夹config,里面所有的文件,都属于在vite.config.ts文件中引用。
├── config
│ ├── build # 构建配置
│ ├── plugins # 插件配置
│ └── utils # 工具函数
├── src
...
-
config/plugins/index.ts: 插件配置文件,用于配置插件,并返回一个vite插件数组import type { PluginOption } from "vite"; import vue from '@vitejs/plugin-vue'; import vueJsx from '@vitejs/plugin-vue-jsx'; import AutoImport from 'unplugin-auto-import/vite'; import Components from 'unplugin-vue-components/vite'; import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'; /** * vite插件 * @returns PluginOption[] */ export const setupVitePlugins = (): PluginOption[] => { const plugins = [ vue({ script: { defineModel: true, /** Vite 插件会自动为所有 Vue 组件创建对应的 TypeScript 接口,以增强类型检查的效果 */ } }), vueJsx(), /** tsx jsx 语法支持 */ /** 动导入常用的 API,减少手动导入的繁琐操作 */ AutoImport({ resolvers: [ ElementPlusResolver() ], imports: ['vue'], dts: 'src/types/auto-import.d.ts', /** 指定文件生成位置 */ }), /** 自动注册组件,使得你可以直接在模板中使用全局或局部组件,而无需显式地通过 import 或 components 选项来注册。 */ Components({ resolvers: [ ElementPlusResolver() ], dts: 'src/types/components.d.ts' }), ] return plugins } -
config/build/index.ts:vite.config.ts的其它配置选项,如define、resolve、css等-
index.ts:统一导出文件export * from './define'; -
define.ts:定义环境变量,用于在vite.config.ts中引用import dayjs from 'dayjs'; import pkg from '../../package.json'; /** 项目构建时间 */ const APP_BUILD_TIME = JSON.stringify(dayjs().format('YYYY-MM-DD HH:mm:ss')); interface Package { name: string; version: string; dependencies: Record<string, string>; devDependencies: Record<string, string>; [key: string]: any; } interface PkgVersionInfo { name: string; version: string; } /** 项目信息 */ const { dependencies, devDependencies, name, version } = pkg as Package; function transformVersionData(tuple: [string, string]): PkgVersionInfo { const [name, version] = tuple; return { name, version }; } const APP_PKG_INFO = { name, version, dependencies: Object.entries(dependencies).map(item => transformVersionData(item)), devDependencies: Object.entries(devDependencies).map(item => transformVersionData(item)) }; export const viteDefine = { APP_BUILD_TIME, APP_PKG_INFO }
-
-
config/utils/index.ts: 工具函数,用于封装一些通用的工具函数,如:getLocalIPAddress等import os from 'os'; export const getLocalIPAddress = ():string => { const interfaces = os.networkInterfaces(); for (const interfaceName in interfaces) { const addresses = interfaces[interfaceName] as os.NetworkInterfaceInfo[] for (const address of addresses) { if (address.family === 'IPv4' && !address.internal) { return address.address } } } return 'localhost' } export function isDevelopment(): boolean { return process.env.NODE_ENV === 'development'; } -
vite.config.tsimport type { ConfigEnv, UserConfig } from 'vite'; import { defineConfig, loadEnv } from 'vite'; import { resolve } from "path"; // ./config import { viteDefine } from "./config/build"; import { setupVitePlugins } from "./config/plugins"; import { getLocalIPAddress } from "./config/utils"; // https://vitejs.dev/config/ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { const viteEnv = loadEnv(mode, process.cwd()) as unknown as ImportMetaEnv; return { server: { host: getLocalIPAddress(), port: viteEnv.VITE_PORT, open: false }, define: viteDefine, plugins: setupVitePlugins(), resolve: { alias: { "~": resolve(process.cwd()), "@": resolve(__dirname, 'src'), '@ts': resolve(__dirname, 'src/types'), '@utils': resolve(__dirname, 'src/utils'), '@comps': resolve(__dirname, 'src/components') } }, css: { preprocessorOptions: { scss: { additionalData: '@use "@/styles/scss/variables.scss";', javascriptEnabled: true, } } }, // 打包配置 build: { } } })
4 定义环境变量
.env # 存放不同环境共用的环境变量,定义的变量将被各环境共享
.env.dev # 开发环境 => .env.development
.env.prod # 正式环境 => .env.production
.env.stage # 测试环境 => .env.staging
配置示例:
-
.env# 项目名称 VITE_APP_NAME = "vue-admin-main" -
.env.developmentNODE_ENV = "development" # 端口号 VITE_PORT = 3375 # 接口地址 VITE_APP_BASE_URL = "http://255.255.255.1:8080" -
.env.productionNODE_ENV = "production" VITE_PORT = 3071 VITE_APP_BASE_URL = "http://127.0.0.1:3030"
**NOTE1:**在vite中默认以"VITE_"开头的变量,将被挂载在 import.meta.env 对象上。
NOTE:实现环境变量代码自动提示: 添加全局类型声明(注意tsconfig.json中的include配置是否正确)
// src/types/env.d.ts
interface ImportMetaEnv {
VITE_PORT: number
VITE_APP_BASE_URL: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
// 使用示例:console.log(import.meta.env.VITE_APP_BASE_URL)
// 当写到 import.meta.env. 时会有后面的代码提示
在vite.config.ts中使用示例
// vite.config.ts
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
const viteEnv = loadEnv(mode, process.cwd()) as unknown as ImportMetaEnv;
return {
server: {
port: viteEnv.VITE_PORT,
open: false
},
}
})
5 tsconfig.json的个别配置
项目创建时会自动生成tsconfig.json文件,但部分配置需要自己补充
{
"compilerOptions":{
"strict": true, //启用所有严格类型检查选项
"jsx": "preserve", //指定生成的 JSX 代码样式, preserve模式,在preserve模式下生成代码中会保留JSX以供后续的转换操作使用
"jsxImportSource": "vue",
"noUnusedLocals": false, /*true 时,在编译时检测未使用的局部变量,并生成相应的警告或错误*/
"noUnusedParameters": false, /*true 时,TypeScript 编译器会检测未使用的函数参数,并生成相应的警告*/
"allowJs": true, /* true => 允许编译器编译JS,JSX文件 */
"noImplicitAny": false, /* true => 对具有隐含的 ‘any’ 类型的表达式和声明启用错误报告 */
"skipLibCheck": true, //忽略所有的声明文件( *.d.ts)的类型检查
"forceConsistentCasingInFileNames": true, //禁止对同一个文件的不一致的引用
"composite": true, // 启用项目编译的增量构建和依赖管理,通常与 "references" 配合使用。
"noEmit": true, // 禁止 TypeScript 编译器生成输出文件(如 JavaScript 文件),仅进行类型检查。
"baseUrl": "./", /** 解析非相对模块的基地址,默认是当前目录 */
"paths": { /** 模块名到基于 baseUrl的路径映射的列表 */
"@/*": [ "src/*" ],
"@ts/*": [ "src/types/*" ],
"@utils/*": [ "src/utils/*" ],
"@comps/*": [ "src/components/*" ]
},
/** 指定要包含但在源文件中不引用的类型包名称 */
"types": [
"node",
"vite/client", // 引入 Vite 客户端类型声明,但这只是告诉 TypeScript 编译器项目所依赖的类型声明模块
]
},
/* 指定要包含在编译中的文件或文件夹的模式 */
"include": [
"mock/*.ts",
"src",
"vite.config.ts",
"config/**/*.ts",
"*.config.ts",
"*.config.mts",
],
/* 指定不需要被 TypeScript 编译器编译的文件或文件夹 */
"exclude": ["dist", "node_modules"],
/* 指定项目的依赖关系,引用的其他 TypeScript 配置文件 */
"references": [{ "path": "./tsconfig.node.json" }]
}
4万+

被折叠的 条评论
为什么被折叠?



