vite+vue3+ts项目搭建(1)---项目规范与配置

381 阅读7分钟

源码仓库:github.com/Liangjiahon…

项目创建

  • 目前 Vue 官方已经声明 Vue-CLI 在维护状态,更推荐使用 npm create 创建一个应用,使用该方式创建的Vue 应用默认是 Vite 脚手架的
 pnpm create vue@latest
  • 这里选择使用TS
 ✔ Project name: 项目名称
 ​
 ✔ Add TypeScript?  Yes
 ✔ Add JSX Support? Yes # 这里我选择支持JSX
 ✔ Add Vue Router for Single Page Application development?  Yes # 集成路由
 ✔ Add Pinia for state management?  Yes # 集成Pinia
 ✔ Add Vitest for Unit testing? … No # 我没选择单元测试
 ✔ Add an End-to-End Testing Solution? … No 
 ✔ Add ESLint for code quality? … No / Yes # 集成ESlint
 ✔ Add Prettier for code formatting? … No / Yes # 集成Prettire
 ​
 ...
  • 在应用创建完成后进入项目根目录,安装依赖
 > cd 项目名称
 ​
 > pnpm install
 ​
 > pnpm dev

规范配置

  • 由于项目已经集成了 EslintPrettier,那么就不需要自行安装了
  • 这里仍需安装两个插件
 pnpm i @typescript-eslint/parser vue-eslint-parser -D
  • @typescript-eslint/parserTypeScript 转换成与 estree 兼容的形式
  • vue-eslint-parser 设置 Eslint 的解析器( Eslint 默认的解析器是 EStree )

Eslint配置文件

  • 安装好插件之后晚上 Eslint 的配置
 /* eslint-env node */
 require("@rushstack/eslint-patch/modern-module-resolution");
 ​
 module.exports = {
   root: true, // 停止在父级目录寻找配置文件
   // 启用特定环境的全局变量
   env: {
     browser: true, // 浏览器全局变量
     es6: true, // es6特性
     node: true // Node.js 全局变量和 Node.js 作用域
   },
   parser: "vue-eslint-parser", // 设置解析器
   // 设置解析器相关配置
   parserOptions: {
     parser: "@typescript-eslint/parser", // 将 TypeScript 转换成与 estree 兼容的形式
     ecmaVersion: "latest", // 指定使用的 ECMAScript 版本
     sourceType: "module", // 使用 ECMAScript 模块
     jsxPragma: "Vue", // 将JSX语法解析为Vue元素
     ecmaFeatures: { jsx: true } // 需要使用的额外的语言特性
   },
   extends: [
     "plugin:vue/vue3-recommended",
     "prettier",
     "plugin:prettier/recommended",
     "@vue/eslint-config-typescript",
     "@vue/eslint-config-prettier/skip-formatting",
     "./.eslintrc-auto-import.json"
   ],
   plugins: ["vue"], // 引入指定的插件,此处省略了 eslint-plugin- 前缀
   rules: {
     "vue/script-setup-uses-vars": "warn", // 防止 <template> 中使用的 <script setup> 变量被标记为未用变量
     "vue/multi-word-component-names": "off", // 关闭Vue组件名称必须使用多个单词的规则
     "vue/custom-event-name-casing": "off", // 关闭自定义事件名称必须使用大写字母的规则
     "vue/attributes-order": "off", // 不强制组件属性的排序
     "vue/v-on-event-hyphenation": "off", // 不强制在自定义组件上使用连字符形式的事件名称
     "vue/one-component-per-file": "off", // 不限制每个文件只能有一个组件
     "vue/max-attributes-per-line": "off", // 不限制组件每行最多的属性数量
     "vue/singleline-html-element-content-newline": "off", // 在单行元素中不使用换行符
     "vue/attribute-hyphenation": "off", // 不强制在自定义组件上使用连字符形式的属性名称
     "vue/require-default-prop": "off", // 不强制prop一定要使用默认值
     "@typescript-eslint/no-unused-vars": ["warn", { vars: "all", args: "none" }],
     "@typescript-eslint/no-use-before-define": "off", // 允许变量在定义前使用
     "@typescript-eslint/no-explicit-any": "off", // 允许使用any
     "@typescript-eslint/no-var-requires": "off", // 允许使用require语句
     "@typescript-eslint/no-empty-function": "off", // 允许使用空函数
     "no-return-assign": "off", // 关闭函数中允许使用赋值表达式的规则
     "no-param-reassign": "off", // 关闭函数参数不允许重新赋值的规则
     "guard-for-in": "off", // 关闭for-in循环中需要使用hasOwnProperty()的规则
     "no-unused-vars": ["warn", { vars: "all", args: "none" }], // 警告出现未使用过的变量
     "no-var": "error", // 要求使用 let 或 const 而不是 var
     "no-new": "off",
     "eol-last": "off",
     "no-shadow": "off"
   }
 };

Prettier配置

 module.exports = {
   $schema: "https://json.schemastore.org/prettierrc",
   useTabs: false,
   semi: true,
   tabWidth: 2,
   singleQuote: false,
   printWidth: 100,
   trailingComma: "none",
   bracketSameLine: false,
   endOfLine: "lf",
   bracketSpacing: true,
   requirePragma: false,
   insertPragma: false,
   vueIndentScriptAndStyle: false,
   proseWrap: "never",
   tmlWhitespaceSensitivity: "strict",
   embeddedLanguageFormatting: "auto"
 };

Stylelint配置

 module.exports = {
   root: true,
   // 继承的规则集
   extends: [
     "stylelint-config-standard", // 使用官方推荐的规则集
     "stylelint-config-recommended-less", // 针对less的规则集
     "stylelint-config-standard-vue" // 针对vue单文件组件的CSS规则集
   ], // 使用插件
   plugins: ["stylelint-order"], // 规定CSS书写属性顺序
   // 自定义CSS书写规则
   rules: {
     indentation: 2, // 缩进为2个空格
     "selector-class-pattern": null, // 不强制限制选择器类名的格式
     "keyframes-name-pattern": null, // 不强制限制动画关键帧名称的格式
     "no-empty-source": null, // 不可以使用空的CSS文件
     "alpha-value-notation": "number", // 强制要求alpha值使用数字表示
     "no-descending-specificity": null, // 不强制限制选择器的优先级
     "unicode-bom": "never", // 不强制使用UTF-8编码
     "font-family-no-missing-generic-family-keyword": null, // 不强制限制字体名称
     "declaration-colon-space-after": "always", // 在冒号之后必须有一个空格
     "declaration-colon-space-before": "never", // 在冒号之前不能有空白符
     "number-max-precision": 2, // 限制数字中允许的小数位数
     "unit-no-unknown": [true, { ignoreUnits: ["rpx"] }], // 禁止未知的单位,如rpx
     // 强制要求伪元素选择器使用正确的语法,并忽略 v-deep、v-global、v-slotted 选择器
     "selector-pseudo-element-no-unknown": [
       true,
       { ignorePseudoElements: ["v-deep", "v-global", "v-slotted"] }
     ],
     // 强制要求伪类选择器使用正确的语法,并忽略 v-deep、v-global 选择器
     "selector-pseudo-class-no-unknown": [true, { ignorePseudoClasses: ["deep", "global"] }],
     // 强制要求使用正确的 @ 规则,并忽略一些特殊的less指令
     "at-rule-no-unknown": [
       true,
       {
         ignoreAtRules: ["tailwind", "function", "if", "else", "else-if", "each", "include", "mixin"]
       }
     ],
     // 强制要求 @ 规则之前有空行
     "at-rule-empty-line-before": [
       "always",
       {
         except: ["blockless-after-same-name-blockless", "first-nested"],
         ignore: ["after-comment"],
         ignoreAtRules: ["else", "else-if"]
       }
     ],
     // 指定书写样式的排序
     "order/properties-order": [
       "position",
       "top",
       "right",
       "bottom",
       "left",
       "z-index",
       "display",
       "justify-content",
       "align-items",
       "flex-shrink",
       "float",
       "clear",
       "width",
       "min-width",
       "max-width",
       "height",
       "min-height",
       "max-height",
       "padding",
       "padding-top",
       "padding-right",
       "padding-bottom",
       "padding-left",
       "margin",
       "margin-top",
       "margin-right",
       "margin-bottom",
       "margin-left",
       "font-size",
       "line-height",
       "font-family",
       "text-align",
       "text-justify",
       "text-indent",
       "text-overflow",
       "text-decoration",
       "white-space",
       "color",
       "background",
       "background-position",
       "background-repeat",
       "background-size",
       "background-color",
       "background-clip",
       "border",
       "border-style",
       "border-width",
       "border-color",
       "border-top-style",
       "border-top-width",
       "border-top-color",
       "border-right-style",
       "border-right-width",
       "border-right-color",
       "border-bottom-style",
       "border-bottom-width",
       "border-bottom-color",
       "border-left-style",
       "border-left-width",
       "border-left-color",
       "border-radius",
       "overflow",
       "overflow-x",
       "overflow-y",
       "opacity",
       "filter",
       "list-style",
       "outline",
       "visibility",
       "box-shadow",
       "text-shadow",
       "resize",
       "transition",
       "content"
     ]
   },
   // 为不同类型的文件或语法提供不同的配置和规则
   overrides: [
     {
       files: ["**/*.(less|css|vue|html)"],
       customSyntax: "postcss-less"
     },
     {
       files: ["**/*.(html|vue)"],
       customSyntax: "postcss-html"
     }
   ]
 };

TS配置文件

  • tsconfig.jsonTypeScript 项目中的配置文件,用于指定编译器的行为和编译选项
  • 它可以用来配置 TypeScript 编译器编译项目的各种设置,包括编译目标、模块系统、文件路径、代码质量检查等等
 {
   "compilerOptions": {
     "target": "esnext", // 指定编译之后的版本目录
     "module": "esnext", // 指定要使用的模块化的规范
     "moduleResolution": "node", // 模块解析策略
     "strict": true, // 启动所有类型检查
     "forceConsistentCasingInFileNames": true, // 强制代码中使用的模块文件名必须和文件系统中的文件名保持大小写一致
     "allowSyntheticDefaultImports": true, // 允许导入没有默认导出的模块
     "jsx": "preserve", // 指定jsx代码用于的开发环境:
     "importHelpers": true, // 引入tslib里的复制工具函数,
     "resolveJsonModule": true, // 解析JSON模块
     "noUnusedLocals": false, // 检查未使用的本地变量
     "noUnusedParameters": true, // 检查未使用的函数参数
     "experimentalDecorators": true, // 开启装饰器支持
     "noImplicitAny": false, // 声明变量时可以不进行明确的类型注解
     "skipLibCheck": true, // 跳过检查内置类型定义库
     "baseUrl": "./", // 项目根目录
     "lib": ["esnext", "dom", "dom.iterable", "scripthost"], // 指定要包含在编译中的库文件
     "types": ["node"], // 指定要包含的类型定义文件
     "typeRoots": ["./node_modules/@types/", "./types"], // 指定类型定义文件的搜索目录
     // 指定模块路径映射
     "paths": {
       "@/*": ["./src/*"],
       "@img/*": ["./src/assets/img/*"],
       "#": ["./types/*"]
     }
   },
   // 需要编译的文件
   "include": [
     "src/**/*.ts",
     "src/**/*.d.ts",
     "src/**/*.tsx",
     "src/**/*.vue",
     "types/**/*.d.ts",
     "types/**/*.ts",
     "build/**/*.ts",
     "build/**/*.d.ts",
     "mock/**/*.ts",
     "vite.config.ts"
   ],
   // 排除不需要编译的文件
   "exclude": ["node_modules", "dist", "**/*.js"]
 }

项目其他配置

项目目录结构

 ├── build # 构建相关
 │   ├── config # 配置文件
 │   └── vite # vite配置
 ├── mock # mock接口
 ├── public # 公共静态资源目录
 ├── src # 主目录
 │   ├── api # 接口文件
 │   ├── assets # 资源文件
 │   ├── components # 公共组件
 │   ├── design # 样式文件
 │   ├── directives # 自定义指令
 │   ├── enums # 枚举/常量
 │   ├── hooks # hook
 │   ├── layouts # 布局文件
 │   ├── locales # 多语言
 │   ├── main.ts # 主入口
 │   ├── router # 路由配置
 │   ├── settings # 项目配置
 │   ├── store # 数据仓库
 │   ├── utils # 工具类
 │   └── views # 页面
 ├── types # 全局共享类型配置
 └── vite.config.ts # vite配置文件