小龙色盲色弱检测
103.04M · 2026-02-26
Vue项目在搭建初期应当设定好目标、规范以及结构,以便后期扩展,避免结构混乱,代码难读、难以修改。
文档以vue3和ant-design-vue组件库为例,从零搭建项目,项目依赖如下:
生产依赖
{
"dependencies": {
"@ant-design/icons-vue": "7.0.1",
"ant-design-vue": "4.2.2",
"autoprefixer": "10.4.20",
"axios": "1.7.7",
"less": "4.2.0",
"mockjs": "1.1.0",
"pinia": "2.3.1",
"postcss": "8.5.3",
"tailwindcss": "3.4.17",
"vue": "3.5.27",
"vue-router": "4.4.5"
},
}
开发依赖
{
"devDependencies": {
"@commitlint/config-conventional": "19.7.1",
"@eslint/js": "^9.39.2",
"@types/node": "22.12.0",
"@typescript-eslint/eslint-plugin": "8.26.1",
"@typescript-eslint/parser": "8.26.1",
"@vitejs/plugin-vue": "5.0.4",
"@vue/test-utils": "2.4.6",
"@vue/tsconfig": "^0.8.1",
"commitlint": "19.7.1",
"cssnano": "^7.1.2",
"eslint": "9.17.0",
"eslint-plugin-vue": "9.28.0",
"globals": "^17.3.0",
"happy-dom": "20.5.0",
"husky": "9.1.7",
"lint-staged": "15.2.10",
"prettier": "3.5.3",
"stylelint": "16.12.0",
"stylelint-order": "^7.0.1",
"typescript": "5.9.3",
"unplugin-auto-import": "^21.0.0",
"unplugin-vue-components": "^31.0.0",
"vite": "5.4.21",
"vitest": "2.1.8",
"vue-eslint-parser": "^10.2.0",
"vue-tsc": "2.2.8"
}
}
首先项目建议使用pnpm进行包管理和安装,
node_modules 布局使用符号链接来创建依赖项的嵌套结构。node_modules 中每个包的每个文件都是来自内容可寻址存储的硬链接。(避免重复安装)npm i -g pnpm
在项目生产环境中的依赖,主要考虑项目性质以及UI设计:(由于vue3只能在现代浏览器下运行。所以应该从兼容现代浏览器的版本开始,不需要兼容ie版本)
项目直接使用vite构建vue3+typescript项目
// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
import { resolve, extname } from 'path';
//
export default defineConfig({
plugins: [
vue(),
AutoImport({
// 自动导入常用 API(无需手写 import)
imports: ['vue', 'vue-router', 'pinia'],
resolvers: [
AntDesignVueResolver({
importStyle: 'less',
}),
],
dts: 'src/auto-imports.d.ts', // 生成 `auto-imports.d.ts` 全局 API 类型声明,支持 IDE 代码提示
}),
Components({
resolvers: [
AntDesignVueResolver({
importStyle: 'less', // 这里设置为 'less',以便在使用组件时自动引入对应的 Less 样式文件
}),
],
dts: 'src/components.d.ts', // 生成 `components.d.ts` 全局组件类型声明,支持 IDE 代码提示
}),
],
resolve: {
alias: {
'@': resolve(__dirname, 'src'), // 设置 '@' 代表 'src' 目录,方便在项目中使用绝对路径导入模块
},
},
css: {
preprocessorOptions: {
// 配置 Less 预处理器选项
less: {
javascriptEnabled: true, // 允许在 Less 文件中使用 JavaScript 表达式,这对于 Ant Design Vue 的样式定制非常重要
},
},
},
// 开发服务器配置
server: {
port: 3000,
open: true,
cors: true,
},
build: {
target: 'es2020', // 设置构建目标为 ES2020,利用现代浏览器的特性提升性能
outDir: 'dist',
sourcemap: false,
rollupOptions: {
output: {
// 按类型分类输出文件
entryFileNames: 'assets/js/[name]-[hash].js',
chunkFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: function (assetInfo) {
var _a;
var ext = extname((_a = assetInfo.name) !== null && _a !== void 0 ? _a : '');
if (ext === '.css') {
return 'assets/css/[name]-[hash][extname]';
}
return 'assets/[name]-[hash][extname]';
},
// 将核心依赖单独拆分成独立 chunk,方便 CDN 长效缓存
manualChunks: {
vue: ['vue', 'vue-router', 'pinia'],
antd: ['ant-design-vue', '@ant-design/icons-vue'],
vendor: ['axios'],
},
},
},
},
});
ESLint 用于统一代码风格和查找潜在问题。本项目使用 JS/TS/Vue 分块配置,并根据不同文件类型启用对应规则。
//eslint.config.js
import js from '@eslint/js';
import globals from 'globals';
import vuePlugin from 'eslint-plugin-vue';
import vueParser from 'vue-eslint-parser';
import tseslint from '@typescript-eslint/eslint-plugin';
import tsparser from '@typescript-eslint/parser';
const isProd = process.env.NODE_ENV === 'production';
export default [
// ==================== 基础配置 ====================
{
// 全局忽略的文件和目录
ignores: [
'**/node_modules/**',
'**/dist/**',
'**/build/**',
'**/coverage/**',
'**/public/**',
'**/*.min.js',
'**/*.d.ts',
'**/package-lock.json',
'**/pnpm-lock.yaml',
'**/yarn.lock',
'**/vite.config.d.ts',
'**/vitest.config.d.ts',
],
},
// ==================== JavaScript 通用配置 ====================
{
files: ['**/*.{js,mjs,cjs}'],
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: {
...globals.browser,
...globals.node,
...globals.es2020,
},
},
rules: {
...js.configs.recommended.rules,
// 自定义规则
'no-console': isProd ? ['warn', { allow: ['warn', 'error'] }] : 'off',
'no-debugger': isProd ? 'warn' : 'off',
'no-alert': 'warn',
'no-unused-vars': 'off', // 由 TypeScript 处理
'prefer-const': 'error',
eqeqeq: ['error', 'always'],
curly: ['error', 'all'],
},
},
// ==================== TypeScript 配置 ====================
{
files: ['**/*.{ts,tsx}'],
languageOptions: {
parser: tsparser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
// 使用应用和 Node 两个 tsconfig,提升类型检查覆盖面
project: ['./tsconfig.app.json', './tsconfig.node.json'],
},
globals: {
...globals.browser,
...globals.node,
...globals.es2020,
},
},
plugins: {
'@typescript-eslint': tseslint,
},
rules: {
...tseslint.configs.recommended.rules,
// TypeScript 特定规则
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],
'@typescript-eslint/ban-ts-comment': 'warn',
'@typescript-eslint/no-empty-function': 'warn',
'@typescript-eslint/no-non-null-assertion': 'warn',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-inferrable-types': 'warn',
'@typescript-eslint/consistent-type-imports': [
'warn',
{
prefer: 'type-imports',
disallowTypeAnnotations: false,
},
],
},
},
// ==================== Vue 3 文件配置 ====================
{
files: ['**/*.vue'],
plugins: {
vue: vuePlugin,
},
languageOptions: {
// 使用官方 Vue 解析器对象,支持 <template> + <script setup>
parser: vueParser,
parserOptions: {
parser: tsparser,
ecmaVersion: 'latest',
sourceType: 'module',
extraFileExtensions: ['.vue'],
project: ['./tsconfig.app.json', './tsconfig.node.json'],
},
globals: {
...globals.browser,
},
},
rules: {
// 继承 Vue 3 推荐规则
...vuePlugin.configs['vue3-recommended'].rules,
// ========== Vue 3 自定义规则 ==========
// 1. 组件命名规则(针对 Vue 3 单文件组件)
'vue/multi-word-component-names': [
'error',
{
ignores: [
'index', // index.vue
'App', // App.vue
'404', // 404.vue
'[id]', // 动态路由组件
'[...all]', // 动态路由组件
'Layout', // Layout.vue
'Default', // Default.vue
'Main', // Main.vue
],
},
],
// 2. 组件属性换行规则(针对 Ant Design Vue 属性多的特点)
'vue/max-attributes-per-line': [
'error',
{
singleline: 5, // Ant Design 组件通常属性较多,放宽到5个
multiline: {
max: 1,
},
},
],
// 3. Ant Design Vue 组件名特殊处理(关键配置)
'vue/component-name-in-template-casing': [
'error',
'PascalCase',
{
registeredComponentsOnly: false,
ignores: [
// Ant Design Vue 组件前缀 (a-)
'/^a-/', // a-button, a-input, a-modal
'/^A[A-Z]/', // AButton, AInput
// Vue 内置组件
'router-view',
'router-link',
'transition',
'transition-group',
'keep-alive',
'component',
'slot',
'template',
// 常见第三方组件
'icon',
'icons',
],
},
],
// 4. 其他 Vue 规则调整
'vue/require-default-prop': 'off', // 不要求必须默认值
'vue/no-v-html': 'warn', // 警告使用 v-html
'vue/prop-name-casing': ['error', 'camelCase'], // props 使用驼峰
'vue/attribute-hyphenation': ['error', 'always'], // 属性使用连字符
// 5. 模板内容换行
'vue/html-closing-bracket-newline': [
'error',
{
singleline: 'never',
multiline: 'always',
},
],
// 7. 顺序规则(可选,使代码更整洁)
'vue/attributes-order': [
'error',
{
order: [
'DEFINITION', // is, v-is
'LIST_RENDERING', // v-for
'CONDITIONALS', // v-if, v-else-if, v-else, v-show, v-cloak
'RENDER_MODIFIERS', // v-once, v-pre
'GLOBAL', // id
'UNIQUE', // ref, key, v-slot, v-model
'SLOT', // v-slot
'TWO_WAY_BINDING', // v-model
'OTHER_DIRECTIVES', // v-custom-directive
'OTHER_ATTR', // 其他属性
'EVENTS', // v-on
'CONTENT', // v-text, v-html
],
},
],
},
},
// ==================== 测试文件特殊配置 ====================
{
files: ['**/__tests__/**/*.{js,ts,vue}', '**/*.test.{js,ts,vue}', '**/*.spec.{js,ts,vue}'],
plugins: {
'@typescript-eslint': tseslint,
},
languageOptions: {
parser: tsparser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
globals: {
// 使用 Vitest 全局变量
...globals.vitest,
},
},
rules: {
'no-console': 'off',
'no-debugger': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
// ==================== 配置文件特殊处理 ====================
{
files: ['**/vite.config.{js,ts}', '**/vitest.config.{js,ts}', '**/eslint.config.{js,mjs}', '**/*.config.{js,ts}'],
plugins: {
'@typescript-eslint': tseslint,
},
languageOptions: {
parser: tsparser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
globals: {
...globals.node,
},
},
rules: {
'no-console': 'off',
'@typescript-eslint/no-unused-vars': 'warn',
},
},
];
**/node_modules/**、**/dist/**、**/build/**:依赖与构建输出目录。**/coverage/**:测试覆盖率报告。**/public/**:静态资源目录。**/*.min.js、**/*.d.ts:压缩 JS 与类型声明文件。**/*.{js,mjs,cjs}
latest,使用最新 ECMAScript 语法。module,按 ES Module 解析。browser、node、es2020 全局变量,避免误报。...js.configs.recommended.rules:继承官方 ESLint 推荐规则。no-console:生产环境下仅允许 console.warn / console.error,开发环境关闭。no-debugger:生产环境警告,开发环境关闭。no-alert:使用 alert 时给出警告。no-unused-vars:关闭,由 TypeScript 规则接管。prefer-const:推荐使用 const。eqeqeq:强制使用 === / !==。curly:要求所有控制语句使用大括号。**/*.{ts,tsx}@typescript-eslint/parser,支持 TS 语法。./tsconfig.app.json, ./tsconfig.node.json,启用基于项目的类型信息检查。@typescript-eslint:启用 TS 专用规则。@typescript-eslint 官方 recommended 规则。@typescript-eslint/no-explicit-any:对 any 给出警告。@typescript-eslint/no-unused-vars:检查未使用变量,可通过 _ 前缀忽略。@typescript-eslint/ban-ts-comment:限制 // @ts-ignore 等用法。@typescript-eslint/no-non-null-assertion:对 ! 非空断言警告。@typescript-eslint/explicit-function-return-type:关闭强制显式返回类型。@typescript-eslint/consistent-type-imports:推荐使用 type 导入形式。**/*.vuevue:Vue 官方 ESLint 插件。vue-eslint-parser,支持 <template> + <script setup>。tsconfig.app.json 和 tsconfig.node.json。...vuePlugin.configs['vue3-recommended'].rules:继承 Vue3 推荐规则集。vue/multi-word-component-names:强制组件名多词,忽略特定名称(如 App、Layout、index 等)。vue/max-attributes-per-line:单行最多 5 个属性,多行时每行 1 个,方便 Ant Design Vue 组件阅读。vue/component-name-in-template-casing:模板中组件名强制 PascalCase,但对 a-button 等 Ant Design 组件和部分内置组件放宽。vue/require-default-prop:关闭 props 强制默认值。vue/no-v-html:对 v-html 给出警告。vue/prop-name-casing:props 必须使用 camelCase。vue/attribute-hyphenation:模板属性使用连字符形式。vue/html-closing-bracket-newline:多行标签关闭时必须换行。vue/attributes-order:规范属性书写顺序(如定义、条件、事件等)。**/__tests__/**/*.{js,ts,vue}**/*.test.{js,ts,vue}**/*.spec.{js,ts,vue}globals.vitest,注入 Vitest 的全局(如 describe、it、expect 等)。no-console / no-debugger:在测试中关闭限制。vite.config.{js,ts}、vitest.config.{js,ts}、eslint.config.{js,mjs} 以及 *.config.{js,ts}。no-console:关闭,允许在配置文件中打印调试信息。@typescript-eslint/no-unused-vars:降级为 warn,避免轻微未使用变量导致出错。本项目使用 Prettier 统一代码格式,配置文件为 .prettierrc,并通过 npm script 与 lint-staged 集成,在保存/提交时代码会被自动格式化。
//.prettierrc
{
"printWidth": 150,
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"arrowParens": "avoid",
"vueIndentScriptAndStyle": true,
"htmlWhitespaceSensitivity": "css",
"endOfLine": "lf"
}
通过vscode插件Prettier - Code formatter对代码进行自动格式化。能够更专注于代码逻辑书写。
150
4
false
true
true
"es5"
true
{ foo: bar }。"avoid"
x => x + 1。true
<script> 和 <style> 内容进行缩进。"css"
"lf"
falsetrue 可读性更好,但文件会更长。falsetrue。"as-needed""as-needed"(默认,仅在需要时加引号)、"consistent"(同一对象内保持一致)、"preserve"(保留原样)。false> 是否与最后一行内容在同一行。不同团队习惯不同,可按团队偏好统一。"preserve""always"、"never"、"preserve"。printWidth 处自动换行。文档较多的项目,若希望 diff 更细致、行宽统一,可考虑设为 "always"。"auto""auto"、"off"。"off"。false@format)时才会被 Prettier 格式化。通常用于大型旧项目的“渐进式接入”。false@format 注释,常配合 requirePragma 使用。0 / Infinityfiles / excludeFiles)为不同类型文件指定不同的 Prettier 配置,例如:
*.md 使用不同的 printWidth 或 proseWrap;*.json 关闭某些影响可读性的规则等。format 脚本:prettier --write .
.lintstagedrc 中:
*.{js,ts,vue} 文件:先用 eslint --cache --fix --max-warnings=0 再用 prettier --write,先修复语法/风格问题,再统一格式。*.{css,less,scss}:先用 stylelint --cache --fix 检查样式规范,再用 Prettier 格式化。*.{json,md,html,yml,yaml}:直接使用 prettier --write 进行格式化。本项目使用多层 tsconfig 管理不同环境和用途的 TypeScript 配置:
{
"files": [],
"references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }],
}
tsconfig.app.json 与 tsconfig.node.json,组成 TS 的多工程(project references)结构,便于增量构建和工具支持。{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"ignoreDeprecations": "6.0"
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [
{
"path": "./tsconfig.node.json"
}
]
}
"@vue/tsconfig/tsconfig.dom.json"
"ES2020"
true
["ES2020", "DOM", "DOM.Iterable"]
"ESNext"
true
"bundler"
true
.ts 扩展名文件。true
true
true
"preserve"
true
true
true
"."
"@/*": ["src/*"]@ 别名,使 TS 能理解 @/xxx 导入路径。"src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"
./tsconfig.node.json
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"strict": true
},
"include": ["vite.config.ts", "vitest.config.ts"]
}
true
true
"ESNext"
"bundler"
true
export = 的模块使用默认导入,兼容 CommonJS 包。true
["vite.config.ts", "vitest.config.ts"]
vue-tsc:
- 专门针对 Vue 3 项目(包括 `.vue` 文件)进行类型检查的工具。
- 在 package.json 中通过脚本:
- `type-check`: `vue-tsc -b`
- `build`: `vue-tsc -b && vite build`
- 先基于 tsconfig 工程配置做一遍完整类型检查,再进入 Vite 构建流程,避免类型错误进入打包阶段。
ESLint + @typescript-eslint/*:
- ESLint 使用 `@typescript-eslint/parser` 与 `@typescript-eslint/eslint-plugin` 读取 tsconfig 中的编译选项和类型信息,对 TS/TSX 代码做更精细的规则检查。
- 通过 parserOptions.project 指向 `tsconfig.app.json` / `tsconfig.node.json`,确保类型感知规则(如 no-unused-vars、no-explicit-any 等)能够发挥作用。
Vitest 与 TS:
- vitest.config.ts 通过 mergeConfig 复用 Vite 配置,使测试文件也能使用同样的别名与 TS 配置。
- 测试代码本身的类型检查依托于上述 tsconfig 和 vue-tsc/TypeScript 工具链。
本项目通过 Husky、lint-staged 和 Commitlint 组成一套 Git 提交前检查与提交消息规范校验流程。
.husky/pre-commit
.husky/commit-msg
package.json 中:
"prepare": "husky"
文件:.husky/pre-commit
内容:
# 严格模式:提交前必须通过 lint-staged 检查
pnpm lint-staged
含义:
git commit 时,只对暂存区(staged)的文件运行 lint-staged。文件:.lintstagedrc
核心规则:
{
"*.{js,ts}": ["eslint --cache --fix --max-warnings=0", "prettier --write"],
"*.vue": ["eslint --cache --fix --max-warnings=0", "prettier --write"],
"*.{css,less,scss}": ["stylelint --cache --fix", "prettier --write"],
"*.{json,md,html,yml,yaml}": "prettier --write",
"src/**/components/**/*.{vue,js,ts}": ["eslint --cache --fix --max-warnings=5"],
"src/**/antd/**/*.{vue,js,ts}": ["eslint --cache --fix --max-warnings=5"],
}
说明:
*.{js,ts} / *.vue
*.{css,less,scss}
*.{json,md,html,yml,yaml}
src/**/components/**/*.{vue,js,ts} 与 src/**/antd/**/*.{vue,js,ts}
文件:.husky/commit-msg
内容:
# 严格模式:提交信息必须符合规范,否则中断提交
pnpm commitlint --edit "$1"
含义:
文件:.commitlintrc.cjs
核心规则:
// .commitlintrc.cjs
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
// 1. 提交类型(必需)
'type-enum': [
2,
'always',
[
'feat', // 新功能
'fix', // Bug修复
'docs', // 文档更新
'style', // 代码格式(空格、分号等,不影响功能)
'refactor', // 重构(既不是新功能也不是bug修复)
'test', // 测试相关
'chore', // 构建过程或辅助工具变动
'perf', // 性能优化
'build', // 构建系统或外部依赖变更
'ci', // CI配置变更
'revert', // 回滚提交
'other', // 其他类型
],
],
// 2. 类型必须小写
'type-case': [2, 'always', 'lower-case'],
// 3. 类型不能为空
'type-empty': [2, 'never'],
// 4. 主题(描述)不能为空
'subject-empty': [2, 'never'],
// 5. 主题不以句号结尾
'subject-full-stop': [2, 'never', '.'],
// 6. 主题最少3个字符
'subject-min-length': [2, 'always', 3],
// 7. 主题最多100个字符(建议一行能显示完整)
'subject-max-length': [2, 'always', 100],
// 8. 作用域(可选)
'scope-enum': [
2,
'always',
[
'component', // 组件
'page', // 页面
'layout', // 布局
'router', // 路由
'store', // 状态管理(Pinia)
'api', // API接口
'utils', // 工具函数
'styles', // 样式
'types', // TypeScript类型
'config', // 配置
'deps', // 依赖更新
'other', // 其他(不属于以上分类的提交)
],
],
},
};
关键点:
extends:['@commitlint/config-conventional']
type-enum
feat、fix、docs、style、refactor、test、chore、perf、build、ci、revert、other 等。type-case / type-empty
subject-empty / subject-min-length / subject-max-length
subject-full-stop 规则)。scope-enum
component、page、layout、router、store、api、utils、styles、types、config、deps、other 等,帮助约束“这个提交主要改了哪一类东西”。pnpm lint、pnpm format 保持代码整洁。feat(component): 新增用户列表组件fix(api): 修复登录接口返回值解析错误PostCSS 用于在构建过程中对 CSS 进行各种自动化处理。本配置主要启用了 Tailwind CSS、Autoprefixer 以及在生产环境使用的 cssnano 压缩。
// postcss.config.cjs
module.exports = {
plugins: {
// Tailwind CSS 插件
tailwindcss: {
config: './tailwind.config.js', // 指定 Tailwind 配置文件路径
},
// Autoprefixer 自动添加浏览器前缀
autoprefixer: {
overrideBrowserslist: [
'last 2 versions', // 支持最近2个版本的浏览器
'> 1%', // 全球使用率 > 1% 的浏览器
'ios >= 8', // iOS 8+
'android >= 4.4', // Android 4.4+
'not ie <= 11', // 不支持 IE 11 及以下
'not dead', // 不包含已死亡的浏览器
],
grid: true, // 为 IE 启用 CSS Grid 前缀
flexbox: true, // 为旧版浏览器添加 Flexbox 前缀
remove: false, // 不删除过时的前缀
},
// 可选:CSS 压缩(生产环境)
...(process.env.NODE_ENV === 'production'
? {
cssnano: {
preset: [
'default',
{
discardComments: { removeAll: true }, // 删除所有注释
normalizeWhitespace: false, // 不压缩空格(由构建工具处理)
},
],
},
}
: {}),
},
};
'./tailwind.config.js'
last 2 versions:支持最近 2 个版本的各主流浏览器。> 1%:全球使用率大于 1% 的浏览器。ios >= 8:支持 iOS 8 及以上版本。android >= 4.4:支持 Android 4.4 及以上版本。not ie <= 11:排除 IE11 及以下版本。not dead:排除已经停止维护的“死亡”浏览器。true
true
false
process.env.NODE_ENV === 'production' 时才添加该插件。'default':使用 cssnano 默认优化策略。true,删除所有 CSS 注释。false,不在此处压缩空白字符(交由构建工具处理)。该文件定义了 Tailwind CSS 的扫描范围、主题扩展以及与 Ant Design Vue 的配合策略。
// tailwind.config.js(精简版)
module.exports = {
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
theme: {
extend: {
// Ant Design 主题颜色
colors: {
primary: '#1890ff',
success: '#52c41a',
warning: '#faad14',
error: '#f5222d',
info: '#13c2c2',
},
// 字体
fontFamily: {
sans: ['-apple-system', 'BlinkMacSystemFont', '"Segoe UI"', 'Roboto', '"Helvetica Neue"', 'Arial', 'sans-serif'],
},
// 圆角
borderRadius: {
ant: '6px',
},
// 阴影
boxShadow: {
ant: '0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05)',
},
},
// 响应式断点
screens: {
xs: '480px',
sm: '640px',
md: '768px',
lg: '1024px',
xl: '1280px',
'2xl': '1536px',
},
},
// 关键:禁用 preflight 避免与 Ant Design 冲突
corePlugins: {
preflight: false,
},
plugins: [],
};
['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}']
colors:
#1890ff#52c41a#faad14#f5222d#13c2c2fontFamily.sans:
['-apple-system', 'BlinkMacSystemFont', '"Segoe UI"', 'Roboto', '"Helvetica Neue"', 'Arial', 'sans-serif']borderRadius.ant:
6px,用于配合 Ant Design 的默认圆角风格,可在项目中通过自定义类统一使用。boxShadow.ant:
480px640px768px1024px1280px1536px这些断点用于响应式布局,如 md:w-1/2 表示在 md 及以上宽度时占一半宽度。
false
[](空数组)。
Vitest 是与 Vite 深度集成的测试框架。本配置基于 Vite 配置进行扩展,使测试环境与实际构建环境保持一致。
import { mergeConfig } from 'vitest/config';
import viteConfig from './vite.config';
export default mergeConfig(viteConfig, {
test: {
globals: true,
environment: 'happy-dom',
include: ['src/**/*.{test,spec}.{js,ts,vue}'],
},
});
import { mergeConfig } from 'vitest/config'
import viteConfig from './vite.config'
export default mergeConfig(viteConfig, { ... })
true
describe、it、expect 等,无需手动 import。'happy-dom'
['src/**/*.{test,spec}.{js,ts,vue}']
.test. 或 .spec.。describe 等被报未定义。本文档说明本项目主要目录的作用和推荐使用方式,便于团队成员快速理解和扩展。
├─ src/
│ ├─ assets/
│ │ ├─ images/
│ │ └─ styles/
│ ├─ components/
│ │ ├─ common/
│ │ └─ business/
│ ├─ layouts/
│ ├─ router/
│ │ └─ modules/
│ ├─ services/
│ │ └─ modules/
│ ├─ stores/
│ │ └─ modules/
│ ├─ hooks/
│ ├─ utils/
│ ├─ types/
│ ├─ constants/
│ ├─ tests/
│ │ ├─ unit/
│ │ └─ components/
│ ├─ App.vue
│ └─ main.ts
├─ public/
├─ doc/
│ ├─ project-structure.md
│ └─ ...(其他配置/规范文档)
├─ package.json
├─ vite.config.ts / vite.config.js
├─ vitest.config.ts / vitest.config.js
├─ tsconfig*.json
├─ eslint.config.js
├─ tailwind.config.js
└─ .prettierrc
src/
public/
doc/
src/main.ts
src/App.vue
src/assets/
images/、styles/ 等。src/components/
common/(基础通用)、business/(跨页面业务组件)等。src/views/
views/user/List.vue、views/user/components/UserTable.vue。src/layouts/
DefaultLayout.vue、AuthLayout.vue 等。src/router/
index.ts(创建 router 实例)、按模块拆分的路由配置文件(如 modules/user.ts)。src/stores/
userStore.ts、appStore.ts 等。src/services/
request.ts:封装 Axios/Fetch,统一处理请求、响应、错误。user.ts、auth.ts、system.ts。src/utils/
date.ts、format.ts、validator.ts 等。src/hooks/
use 开头,例如:useRequest、usePagination、useDialog 等。src/types/
user.d.ts、auth.d.ts、api.d.ts 等。src/constants/
route-names.ts、storage-keys.ts、business.ts。src/tests/
tests/unit/(工具函数、逻辑单元)和 tests/components/(组件相关测试)。*.test.ts 或 *.spec.ts,Vitest 已在 vitest.config.ts 中配置 include: ['src/**/*.{test,spec}.{js,ts,vue}'],会自动匹配。以下为项目中推荐使用的一些二级子目录,实际可根据业务扩展或精简:
src/assets/images/
src/assets/styles/
src/components/common/
src/components/business/
src/views/dashboard/
src/router/modules/
system.ts、user.ts、dashboard.ts。src/stores/modules/
system.ts、user.ts、app.ts 等。src/services/modules/
system.ts、user.ts、auth.ts 等。