Appearance
安装插件: ESLint
安装插件:Prettier - Code formatter
安装 NPM 包
sh
npm i @eslint/js@10.0.1 eslint@9.39.4 eslint-config-prettier@10.1.8 eslint-plugin-prettier@5.5.5 eslint-plugin-vue@10.9.0 fs-extra@11.3.4 globals@17.6.0 prettier@3.8.3 typescript-eslint@8.59.1 prettier-plugin-tailwindcss@0.6.14 eslint-plugin-import@2.32.0 eslint-import-resolver-typescript@4.4.4 -D.prettierrc
{
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "none",
"arrowParens": "avoid",
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindAttributes": [
"class",
"ui"
]
}eslint.config.js
js
import js from '@eslint/js'
import { defineConfig } from 'eslint/config'
import pluginImport from 'eslint-plugin-import'
import pluginPrettier from 'eslint-plugin-prettier'
import pluginVue from 'eslint-plugin-vue'
import globals from 'globals'
import tseslint from 'typescript-eslint'
export default defineConfig([
// 继承 js 官方推荐规则
js.configs.recommended,
// 继承 ts 官方推荐规则
...tseslint.configs.recommended,
// 继承 import 插件推荐规则
pluginImport.flatConfigs.recommended,
// 继承 vue 基础规则(flat 格式)
pluginVue.configs['flat/essential'],
{
files: ['**/*.{js,mjs,cjs,ts,vue}'],
languageOptions: {
// 声明运行在浏览器环境,实现在使用 window、document 等浏览器内置变量时不报错
globals: globals.browser,
// 支持最新 es 语法
ecmaVersion: 'latest',
// 使用 es module
sourceType: 'module'
},
rules: {
// 以下规则全部移至 .prettierrc 文件,通过让 prettier 作为 eslint 规则实现这
// 些功能,eslint 只做语法检查
// semi: ['error', 'never'], // 必须加分号,改为 "never" 表示不加分号
// quotes: ['error', 'single'], // 必须用双引号,改为 "double" 表示双引号
// indent: ['error', 2], // 2 空格缩进
// 'arrow-parens': ['error', 'as-needed'], // 允许箭头函数只有一个参数时省略括号
// 'comma-dangle': ['error', 'never'], // 允许最后一个属性后不加逗号
// 处理未使用的变量给警告提示,no-unused-vars 和 @typescript-eslint/no-unused-vars
// 只要开启其中一个就可以,否则会造成重复警告,同时需要把 tsconfig.json 中的
// noUnusedLocals 和 noUnusedParameters 注释掉或者设置为 false,不然也会
// 重复警告,因此都不处理的话同一个错会出现三次警告
'no-unused-vars': ['warn'],
'@typescript-eslint/no-unused-vars': 'off',
// ts 通过声明完成的变量还是会被 eslint 的 no-undef 标记为未定义,需要关闭
'no-undef': 'off',
// 允许声明为 any 类型
'@typescript-eslint/no-explicit-any': 'off',
// 允许 ts 注释,如 // @ts-ignore
'@typescript-eslint/ban-ts-comment': 'off',
// 启用 prettier 作为 eslint 规则,eslint 只做 js 代码检测
'prettier/prettier': 'error',
// 排序规则
'import/order': [
'error',
{
groups: [
'builtin', // 1.node 内置模块(fs...)
'external', // 2.第三方包(vue...)
'internal', // 3.项目内部文件(@/utils...)
'parent', // 4.父级文件(../xxx)
'sibling', // 5.同级文件(./xxx)
'index' // 6.入口文件
],
// 不同分组之间空一行
'newlines-between': 'always',
// 按字母顺序排序同时不区分大小写
alphabetize: { order: 'asc', caseInsensitive: true },
pathGroups: [
// @/ 开头的路径归为内部模块
{ pattern: '@/**', group: 'internal', position: 'before' }
],
// node 内置模块不被 pathGroups 规则影响,否则内部模块可能会排到 node 内置
// 模块上面
pathGroupsExcludedImportTypes: ['builtin']
}
]
},
settings: {
// 解析器配置
'import/resolver': {
// 支持 typescript
typescript: true,
// 支持 node
node: true
}
},
// prettier 作为 eslint 规则,格式错误会直接在 ide 里标红
plugins: { prettier: pluginPrettier }
},
{
files: ['**/*.vue'],
rules: {
// 允许组件名不是多单词(如 Home.vue 不会报错,多单词是为了避免和 html 标签冲突)
'vue/multi-word-component-names': 'off',
// 处理标签自闭和
'vue/html-self-closing': [
'error',
{
html: {
void: 'always', // 空元素必须自闭合 <img />
normal: 'never', // 普通标签禁止自闭合 <div></div>
component: 'always' // vue 组件必须自闭合 <MyComponent />
},
svg: 'always', // svg 所有相关标签都允许自闭合
math: 'always' // math 所有相关标签都允许自闭合
}
]
},
languageOptions: {
parserOptions: {
// vue 文件里的 ts 用 ts 解析器
parser: tseslint.parser
}
}
}
]).vscode 目录下的 setting.json
json
{
// .css 文件提供 tailwind 提示
"files.associations": {
"*.css": "tailwindcss"
},
"editor.quickSuggestions": {
"strings": "on"
},
// 组件 class 和 ui 属性开启 tailwind 提示
"tailwindCSS.classAttributes": ["class", "ui"],
"tailwindCSS.experimental.classRegex": [
["ui:\\s*{([^)]*)\\s*}", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
],
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
// 保存自动格式化
"editor.formatOnSave": true,
// 保存自动修复 eslint 问题
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "always"
},
// 换行符使用 lf,而不是 crlf
"files.eol": "\n"
}tsconfig.json
json
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}tsconfig.app.json
json
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
/* Linting */
"strict": false,
// 开启严格空类型检查,让 null / undefined 参与类型检查和推导
"strictNullChecks": true,
// "noUnusedLocals": true,
// "noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
// 让 vscode 识别 @
"paths": { "@/*": ["./src/*"] },
},
"include": ["src/**/*.ts", "src/**/*.vue", "auto-imports.d.ts", "components.d.ts"]
}tsconfig.node.json
json
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": false,
// 开启严格空类型检查,让 null / undefined 参与类型检查和推导
"strictNullChecks": true,
// "noUnusedLocals": true,
// "noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"paths": {
"#build/ui": [
"./node_modules/@nuxt/ui/.nuxt/ui"
]
}
},
"include": ["vite.config.ts"]
}vite.config.js
js
import { resolve } from 'path'
import vue from '@vitejs/plugin-vue'
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'vite'
import ui from '@nuxt/ui/vite'
import { visualizer } from 'rollup-plugin-visualizer'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
ui(),
tailwindcss(),
visualizer({
open: false, // 自动打开分析页面
filename: './rollup-visualizer/index.html', // 输出文件名
gzipSize: true, // 显示 gzip 压缩大小
brotliSize: true // 显示 brotli 压缩大小
})
],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
}
})