# vue3-ts-vite-template
**Repository Path**: LHD86/vue3-ts-vite-template
## Basic Information
- **Project Name**: vue3-ts-vite-template
- **Description**: vue3+ts+vite的前端框架模板
- **Primary Language**: TypeScript
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2023-08-19
- **Last Updated**: 2024-01-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Vue, TypeScript
## README
# Vue 3 + TypeScript + Vite 框架模板
## 一、技术栈
- 请求:axios
- 路由:pinia
- 开发语言:TypeScript
- 构建工具:Vite
- 包管理命令:yarn
## 二、目录文件配置
### 1. 目录结构
```apl
项目文件根目录
- build:
- plugins: 插件目录
- public: 公共资源
- src: 资源目录
- assets: 静态名
- components: 非路由组件组件
- hooks: hook函数文件列表
- router: 路由文件
- store:
- modules:
- styles: 样式文件
- untils: 工具
- views: 路由组件
- types: 公共类型声明
- auto-imports.d.ts: 自动导入配置
- components.d.ts: 组件导入
- vite-env.d.ts: 自定义组件导入
-
```
### 2. vite.config.ts基本配置
```ts
import { UserConfig, ConfigEnv } from 'vite';
import { createVitePlugins } from './build/vite/plugins';
import { resolve } from 'path';
import proxy from './build/vite/proxy';
import { VITE_PORT } from './build/constant';
function pathResolve(dir: string) {
return resolve(process.cwd(), '.', dir);
}
// https://vitejs.dev/config/
export default ({ command }: ConfigEnv): UserConfig => {
const isBuild = command === 'build';
let base: string;
if (command === 'build') {
base = '/fast-vue3/';
} else {
base = '/';
}
return {
base,
resolve: {
alias: [
{
find: 'vue-i18n',
replacement: 'vue-i18n/dist/vue-i18n.cjs.js',
},
// /@/xxxx => src/xxxx
{
find: /\/@\//,
replacement: pathResolve('src') + '/',
},
// /#/xxxx => types/xxxx
{
find: /\/#\//,
replacement: pathResolve('types') + '/',
},
],
},
// plugins
plugins: createVitePlugins(isBuild),
// css
css: {},
// server
server: {
hmr: { overlay: false }, // 禁用或配置 HMR 连接 设置 server.hmr.overlay 为 false 可以禁用服务器错误遮罩层
// 服务配置
port: VITE_PORT, // 类型: number 指定服务器端口;
open: false, // 类型: boolean | string在服务器启动时自动在浏览器中打开应用程序;
cors: false, // 类型: boolean | CorsOptions 为开发服务器配置 CORS。默认启用并允许任何源
host: '0.0.0.0', // IP配置,支持从IP启动
proxy,
},
};
};
```
## 三、封装plugins数组
### 1. 封装插件流程
> 下面是导入插件的流程
- 创建目录,与src目录同级

- 创建插件ts文件

- 在plugins的index.ts文件目录下导入cha'dchad插件ts文件,
> **这个地方是导入插件的地方,创建插件ts文件以后需要在这里导入**
```ts
/**
* @name createVitePlugins
* @description 封装plugins数组统一调用
*/
import { PluginOption } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import VitePluginCertificate from 'vite-plugin-mkcert';
import vueSetupExtend from 'vite-plugin-vue-setup-extend';
import { ConfigSvgIconsPlugin } from './svgIcons';
import { AutoRegistryComponents } from './component';
import { AutoImportDeps } from './autoImport';
import { ConfigMockPlugin } from './mock';
import { ConfigVisualizerConfig } from './visualizer';
import { ConfigCompressPlugin } from './compress';
import { ConfigPagesPlugin } from './pages';
import { ConfigRestartPlugin } from './restart';
import { ConfigProgressPlugin } from './progress';
import { ConfigImageminPlugin } from './imagemin';
import { ConfigUnocssPlugin } from './unocss';
export function createVitePlugins(isBuild: boolean) {
const vitePlugins: (PluginOption | PluginOption[])[] = [
// vue支持
vue(),
// JSX支持
vueJsx(),
// setup语法糖组件名支持
vueSetupExtend(),
// 提供https证书
VitePluginCertificate({
source: 'coding',
}) as PluginOption,
];
// 自动按需引入组件
vitePlugins.push(AutoRegistryComponents());
// 自动按需引入依赖
vitePlugins.push(AutoImportDeps());
// 自动生成路由
vitePlugins.push(ConfigPagesPlugin());
// 开启.gz压缩 rollup-plugin-gzip
vitePlugins.push(ConfigCompressPlugin());
// 监听配置文件改动重启
vitePlugins.push(ConfigRestartPlugin());
// 构建时显示进度条
vitePlugins.push(ConfigProgressPlugin());
// unocss
vitePlugins.push(ConfigUnocssPlugin());
// vite-plugin-svg-icons
vitePlugins.push(ConfigSvgIconsPlugin(isBuild));
// vite-plugin-mock
vitePlugins.push(ConfigMockPlugin(isBuild));
// rollup-plugin-visualizer
vitePlugins.push(ConfigVisualizerConfig());
vitePlugins.push(ConfigImageminPlugin());
return vitePlugins;
}
```
- 在vite.config.ts中导入插件(只操作一次)
```ts
import { UserConfig, ConfigEnv } from 'vite';
import { createVitePlugins } from './build/vite/plugins';
import { resolve } from 'path';
import proxy from './build/vite/proxy';
import { VITE_PORT } from './build/constant';
function pathResolve(dir: string) {
return resolve(process.cwd(), '.', dir);
}
// https://vitejs.dev/config/
export default ({ command }: ConfigEnv): UserConfig => {
const isBuild = command === 'build';
let base: string;
if (command === 'build') {
base = '/fast-vue3/';
} else {
base = '/';
}
return {
base,
// plugins
plugins: createVitePlugins(isBuild),
// css
css: {},
};
};
```
### 2. 常用的插件
#### (1)按需自动导入API
> 在此导入以后会自动导入使用的组件比如**ref**,组件中不用在声明
- 安装插件
```shell
npm i -D unplugin-auto-import
yarn add -D unplugin-auto-import
```
- 创建autoImport.ts
```ts
/**
* @name AutoImportDeps
* @description 按需加载,自动引入
*/
import AutoImport from 'unplugin-auto-import/vite';
export const AutoImportDeps = () => {
return AutoImport({
dts: 'types/auto-imports.d.ts',
imports: [
'vue',
'pinia',
'vue-router',
{
'@vueuse/core': [],
},
],
});
};
```
- 导入插件
```ts
/**
* @name createVitePlugins
* @description 封装plugins数组统一调用
*/
import { PluginOption } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import VitePluginCertificate from 'vite-plugin-mkcert';
import vueSetupExtend from 'vite-plugin-vue-setup-extend';
import { AutoRegistryComponents } from './component';
export function createVitePlugins(isBuild: boolean) {
const vitePlugins: (PluginOption | PluginOption[])[] = [
// vue支持
vue(),
// JSX支持
vueJsx(),
// setup语法糖组件名支持
vueSetupExtend(),
// 提供https证书
VitePluginCertificate({
source: 'coding',
}) as PluginOption,
];
// 自动按需引入组件
vitePlugins.push(AutoRegistryComponents());
return vitePlugins;
}
```
- 使用示例
> 以下是自动生成的文件,
```ts
// Generated by 'unplugin-auto-import'
export {};
declare global {
const reactive: typeof import('vue')['reactive'];
const ref: typeof import('vue')['ref'];
.....
}
```
> 组件中使用
```vue
{{count}}
```
#### (2)按需自动导入组件
- 安装插件
```shell
npm install unplugin-vue-components -D
yarn add unplugin-vue-components -D
```
- 创建component.ts
```ts
/**
* @name AutoRegistryComponents
* @description 按需加载,自动引入组件
*/
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver, VueUseComponentsResolver } from 'unplugin-vue-components/resolvers';
export const AutoRegistryComponents = () => {
return Components({
dirs: ['src/components'],
extensions: ['vue'],
deep: true,
// 需要创建相应的文件夹
dts: 'types/components.d.ts',
directoryAsNamespace: false,
globalNamespaces: [],
directives: true,
importPathTransform: (v) => v,
allowOverrides: false,
include: [/\.vue$/, /\.vue\?vue/],
exclude: [/[\\/]node_modules[\\/]/, /[\\/]\.git[\\/]/, /[\\/]\.nuxt[\\/]/],
resolvers: [ElementPlusResolver(), VueUseComponentsResolver()],
});
};
```
- 在上面导入插件
#### (3)按需导入svg
- 安装插件
```shell
yarn add -D vite-plugin-svg-icons
```
- 创建src/assets/icons文件夹
- 在src\components\SvgIcon文件夹下创建index.ts,内容如下
```ts
```
- 在main.ts配置信息
```ts
import { createApp } from 'vue';
import App from './App.vue';
// 支持SVG
import 'virtual:svg-icons-register';
createApp(App).mount('#app');
```
- svg的使用
```vue
```
#### (4)其他插件
> 安装都是
>
> ```shell
> yarn add -D vite-plugin-compression
> x yarn add -D 插件名
>
> ```
- **compress.ts**
```ts
/**
* @name ConfigCompressPlugin
* @description 开启.gz压缩
*/
import viteCompression from 'vite-plugin-compression';
import { COMPRESSION } from '../../constant';
export const ConfigCompressPlugin = () => {
if (COMPRESSION) {
return viteCompression({
verbose: true, // 默认即可
disable: false, //开启压缩(不禁用),默认即可
deleteOriginFile: false, //删除源文件
threshold: 10240, //压缩前最小文件大小
algorithm: 'gzip', //压缩算法
ext: '.gz', //文件类型
});
}
return [];
};
```
- **imagemin.ts**
```ts
import viteImagemin from 'vite-plugin-imagemin';
export function ConfigImageminPlugin() {
const plugin = viteImagemin({
gifsicle: {
optimizationLevel: 7,
interlaced: false,
},
mozjpeg: {
quality: 20,
},
optipng: {
optimizationLevel: 7,
},
pngquant: {
quality: [0.8, 0.9],
speed: 4,
},
svgo: {
plugins: [
{
name: 'removeViewBox',
},
{
name: 'removeEmptyAttrs',
active: false,
},
],
},
});
return plugin;
}
```
- **mock.ts**
```ts
/**
* @name ConfigMockPlugin
* @description 引入mockjs,本地模拟接口
*/
import { viteMockServe } from 'vite-plugin-mock';
export const ConfigMockPlugin = (isBuild: boolean) => {
return viteMockServe({
ignore: /^\_/,
mockPath: 'mock',
localEnabled: !isBuild,
prodEnabled: false, //实际开发请关闭,会影响打包体积
// https://github.com/anncwb/vite-plugin-mock/issues/9
injectCode: `
import { setupProdMockServer } from '../mock/_createProdMockServer';
setupProdMockServer();
`,
});
};
```
- pages.ts
```ts
/**
* @name ConfigPagesPlugin
* @description 动态生成路由
*/
import Pages from 'vite-plugin-pages';
export const ConfigPagesPlugin = () => {
return Pages({
pagesDir: [{ dir: 'src/views', baseRoute: '' }],
extensions: ['vue', 'md'],
exclude: ['**/components/*.vue'],
nuxtStyle: true,
});
};
```
- **progress.ts**
```ts
/**
* @name ConfigProgressPlugin
* @description 构建显示进度条
*/
import progress from 'vite-plugin-progress';
export const ConfigProgressPlugin = () => {
return progress();
};
```
- **restart.ts**
```ts
/**
* @name ConfigRestartPlugin
* @description 监听配置文件修改自动重启Vite
*/
import ViteRestart from 'vite-plugin-restart';
export const ConfigRestartPlugin = () => {
return ViteRestart({
restart: ['*.config.[jt]s', '**/config/*.[jt]s'],
});
};
```
- visualizer.ts
```ts
/**
* @name ConfigUnocssPlugin
* @description 监听配置文件修改自动重启Vite
*/
// Unocss
import Unocss from 'unocss/vite';
export const ConfigUnocssPlugin = () => {
return Unocss();
};
```
### 3. 手动导入模块
- vite-env.d.ts文件
> 经常会有导入其他模块
```ts
///
// 导入自定义组件
declare module '*.vue' {
import { DefineComponent } from 'vue';
const component: DefineComponent<{}, {}, any>;
export default component;
}
declare module 'virtual:*' {
const result: any;
export default result;
}
// 样式库模块
declare module 'element-plus';
```
## 四、配置代码检查 (eslint)
### 1. eslint安装
- 安装插件
```shell
npm i eslint -D
yarn add eslint -D
pnpm add eslint -D
# 安装eslint
npm install eslint --save-dev
# window如果无法运行上述命令,可尝试
"node_modules/.bin/eslint" --init
```
- 初始化eslint配置文件
> 配置文件不是一步生成的,这里是要在终端进行进一步的选择,比如你使用的框架,使用的语言,代码模块化的风格等等
```shell
# 初始化配置,eslint同时可作为命令行工具使用
./node_modules/.bin/eslint --init
# window如果无法运行上述命令,可尝试
"node_modules/.bin/eslint" --init
# 初始化配置
npx eslint --init
```
- **vite集成eslint**
> 安装一个插件ts
>
> ```shell
> yarn add vite-plugin-eslint -D
> ```
```json
import { defineConfig } from 'vite'
import eslint from 'vite-plugin-eslint'
export default defineConfig({
plugins: [
eslint({
include: ['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.vue'],
exclude: ['node_modules'],
cache:false
})
]
})
```
### 2. eslint配置
#### (1)配置.eslintrc.cjs
- 在配置文件中添加规则
> eslint的规则往往是公司项目领导来决定,**下面是一个简单的模板**
```json
rules: {
// eslint(https://eslint.bootcss.com/docs/rules/)
'no-var': 'error', // 要求使用 let 或 const 而不是 var
'no-multiple-empty-lines': ['warn', { max: 1 }], // 不允许多个空行
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-unexpected-multiline': 'error', // 禁止空余的多行
'no-useless-escape': 'off', // 禁止不必要的转义字符
// typeScript (https://typescript-eslint.io/rules)
'@typescript-eslint/no-unused-vars': 'error', // 禁止定义未使用的变量
'@typescript-eslint/prefer-ts-expect-error': 'error', // 禁止使用 @ts-ignore
'@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。
'@typescript-eslint/semi': 'off',
// eslint-plugin-vue (https://eslint.vuejs.org/rules/)
'vue/multi-word-component-names': 'off', // 要求组件名称始终为 “-” 链接的单词
'vue/script-setup-uses-vars': 'error', // 防止