2024最新vite + vue3 配置eslint prettier stylelint husky lint-staged husky commitlint

vite + vue3 配置eslint prettier stylelint husky lint-staged husky commitlint

引言

为了项目团队统一编码风格以及对代码的约束,故引入以下依赖及配置。

第一步 安装依赖

依赖包若有兼容性问题,请查看下方具体的版本号

yarn add eslint@8.57.0 --dev

yarn add prettier eslint-config-prettier eslint-config-airbnb-base eslint-plugin-import eslint-plugin-vue eslint-plugin-prettier vite-plugin-eslint --dev

yarn add stylelint stylelint-config-recess-order stylelint-config-recommended-scss stylelint-config-standard
stylelint-config-standard-scss stylelint-config-standard-vue --dev

yarn add lint-staged --dev

yarn add husky @commitlint/cli @commitlint/config-conventional commitizen cz-git --dev

eslint

代码规则定义及检测工具

prettier

代码风格定义及检测工具

eslint-plugin-import

airbnb所需的依赖,检测js import语句是否正确

eslint-config-prettier

配置eslint规则的prettier包,可以禁用 Prettier与 ESLint冲突的规则。

eslint-config-airbnb-base

airbnb风格的代码规范

eslint-plugin-vue

可以对.vue文件的代码进行检查

eslint-plugin-prettier

使用 Prettier风格格式化代码

vite-plugin-eslint

在vite运行时检测代码是否符合eslint规范

stylelint

stylelint 核心库

stylelint-config-recess-order

css 属性的排序(插件包)

stylelint-config-recommended-scss

扩展 stylelint-config-recommended 共享配置,并为 SCSS 配置其规则

stylelint-config-standard

打开额外的规则来执行在规范和一些 CSS 样式指南中发现的通用约定,包括:惯用 CSS 原则,谷歌的 CSS 样式指南,Airbnb 的样式指南,和 @mdo 的代码指南。

stylelint-config-standard-scss

扩展 stylelint-config-standard 共享配置,并为 SCSS 配置其规则

stylelint-config-standard-vue

扩展 stylelint-config-standard 配置,并为 Vue 配置其规则

lint-staged

扫描暂存区的文件

@commitlint/cli @commitlint/config-conventional

校验commit是否符合规范

commitizen

git commit 终端可视化交互工具

与 cz-git 配合使用

cz-git

与commitizen配合使用

第二步 vscode安装扩展及相关配置文件

vs code安装扩展

vscode中安装eslint、prettier、stylelint扩展

项目根目录新建配置文件

.eslintrc.cjs
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
    es6: true,
  },
  // 指定如何解析语法
  parser: 'vue-eslint-parser',
  // 优先级低于 parse 的语法解析配置
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    ecmaFeatures: {
      jsx: false,
    },
  },

  // 继承某些已有的规则
  extends: [
    'plugin:vue/vue3-recommended', // 使用插件支持vue3
    'airbnb-base',
    'plugin:prettier/recommended',
    './.eslintrc-auto-import.json',
  ],
  /**
   * "off" 或 0  ==>  关闭规则
   * "warn" 或 1 ==>  打开的规则作为警告(不影响代码执行)
   * "error" 或 2 ==>  规则作为一个错误(代码不能执行,界面报错)
   */
  rules: {
    // eslint (http://eslint.cn/docs/rules)
    'prettier/prettier': 'error',
    'import/extensions': 0,
    'prefer-template': 0,
    'no-var': 'error', // 要求使用 let 或 const 而不是 var
    'no-multiple-empty-lines': ['error', { max: 1 }], // 不允许多个空行
    'prefer-const': 'off', // 使用 let 关键字声明但在初始分配后从未重新分配的变量,要求使用 const
    'no-use-before-define': 'off', // 禁止在 函数/类/变量 定义之前使用它们
    'no-irregular-whitespace': 'off', // 禁止不规则的空白\
    'import/no-cycle': 0,
    'no-nested-ternary': 0,
    'import/prefer-default-export': 0,
    'import/no-unresolved': 0,
    'prefer-destructuring': 0,
    'no-shadow': 0,
    'no-param-reassign': 0,
    'consistent-return': 0,
    'no-case-declarations': 0,
    'prefer-promise-reject-errors': 0,
    'jsx-a11y/click-events-have-key-events': 0,
    'jsx-a11y/no-static-element-interactions': 0,
    camelcase: 0,
    'import/no-extraneous-dependencies': 0,
    'no-underscore-dangle': 0,
    'no-debugger': 0,
    'no-promise-executor-return': 0,
    // vue (https://eslint.vuejs.org/rules)
    'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用,此规则仅在启用该no-unused-vars规则时有效。
    'vue/v-slot-style': 'error', // 强制执行 v-slot 指令样式
    'vue/no-mutating-props': 'off', // 不允许组件 prop的改变
    'vue/no-v-html': 'off', // 禁止使用 v-html
    'vue/custom-event-name-casing': 'off', // 为自定义事件名称强制使用特定大小写
    'vue/attributes-order': 'off', // vue api使用顺序,强制执行属性顺序
    'vue/one-component-per-file': 'off', // 强制每个组件都应该在自己的文件中
    'vue/html-closing-bracket-newline': 'off', // 在标签的右括号之前要求或禁止换行
    'vue/max-attributes-per-line': 'off', // 强制每行的最大属性数
    'vue/multiline-html-element-content-newline': 'off', // 在多行元素的内容之前和之后需要换行符
    'vue/singleline-html-element-content-newline': 'off', // 在单行元素的内容之前和之后需要换行符
    'vue/attribute-hyphenation': 'off', // 对模板中的自定义组件强制执行属性命名样式
    'vue/require-default-prop': 'off', // 此规则要求为每个 prop 为必填时,必须提供默认值
    'vue/multi-word-component-names': 'off', // 要求组件名称始终为 “-” 链接的单词
    'vue.prefer-template': 'off',
    'vuejs-accessibility/click-events-have-key-events': 'off',
  },
};

.eslintignore
dist
node_modules
public
.husky
.bin
docs
html
.vscode
.idea
*.sh
*.md
.prettierrc.json

这里建议使用json配置文件而不是cjs或js配置文件,经测试不同版本可能会出现问题

{
  "printWidth": 100,
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "singleQuote": true,
  "quoteProps": "as-needed",
  "jsxSingleQuote": false,
  "trailingComma": "es5",
  "bracketSpacing": true,
  "jsxBracketSameLine": false,
  "bracketSameLine": false,
  "arrowParens": "avoid",
  "endOfLine": "auto",
  "embeddedLanguageFormatting": "auto",
  "vueIndentScriptAndStyle": true,
  "singleAttributePerLine": false,
  "htmlWhitespaceSensitivity": "css",
  "requirePragma": false,
  "insertPragma": false,
  "proseWrap": "preserve"
}
.prettierignore
dist
build
node_modules
public
.husky
.bin
docs
html
.vscode
.idea
*.sh
*.md
.stylelintrc.cjs
// @see https://stylelint.bootcss.com/
module.exports = {
  extends: [
    'stylelint-config-standard', // 配置stylelint拓展插件
    'stylelint-config-html/vue', // 配置 vue 中 template 样式格式化
    'stylelint-config-standard-scss', // 配置stylelint scss插件
    'stylelint-config-recommended-vue/scss', // 配置 vue 中 scss 样式格式化
    'stylelint-config-recess-order', // 配置stylelint css属性书写顺序插件,
    // 'stylelint-config-prettier', // 配置stylelint和prettier兼容, 注意stylelint大于等于v15是已经不需要此插件
  ],
  overrides: [
    {
      files: ['**/*.(scss|css|vue|html)'],
      customSyntax: 'postcss-scss',
    },
    {
      files: ['**/*.(html|vue)'],
      customSyntax: 'postcss-html',
    },
  ],
  ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts', '**/*.json', '**/*.md', '**/*.yaml'],
  /**
   * null  => 关闭该规则
   * always => 必须
   */
  rules: {
    'font-family-no-missing-generic-family-keyword': null,
    'value-keyword-case': null, // 在 css 中使用 v-bind,不报错
    'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
    'function-url-quotes': 'always', // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
    'no-empty-source': null, // 关闭禁止空源码
    'selector-class-pattern': null, // 关闭强制选择器类名的格式
    'property-no-unknown': null, // 禁止未知的属性(true 为不允许)
    // 'block-opening-brace-space-before': 'always', //大括号之前必须有一个空格或不能有空白符
    'value-no-vendor-prefix': null, // 关闭 属性值前缀 --webkit-box
    'property-no-vendor-prefix': null, // 关闭 属性前缀 -webkit-mask
    'scss/dollar-variable-pattern': null,
    'scss/at-mixin-pattern': null,
    'selector-pseudo-class-no-unknown': [
      // 不允许未知的选择器
      true,
      {
        ignorePseudoClasses: ['global', 'v-deep', 'deep'], // 忽略属性,修改element默认样式的时候能使用到
      },
    ],
  },
};

.stylelintignore
/.husky/*
/.vscode/*
/bin
/node_modules/*
/docs/*
/html/*
/dist/*
/public/*
/scripts/*
.lintstagedrc.json
{
  "src/**/*.{vue,js}": [
    "npm run prettier",
    "npm run eslint"
  ],
  "src/**/*.{vue,scss,css,less}": [
    "npm run stylelint:out"
  ]
}
.commitlintrc.cjs
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'body-leading-blank': [1, 'always'],
    'body-max-line-length': [2, 'always', 100],
    'footer-leading-blank': [1, 'always'],
    'footer-max-line-length': [1, 'always', 100],
    'header-max-length': [2, 'always', 100],
    'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
    'subject-empty': [2, 'never'],
    'subject-full-stop': [2, 'never', '.'],
    'type-case': [2, 'always', 'lower-case'],
    'type-empty': [2, 'never'],
    'type-enum': [
      2,
      'always',
      [
        'build',
        'chore',
        'ci',
        'docs',
        'feat',
        'fix',
        'perf',
        'refactor',
        'revert',
        'style',
        'test',
        'conflict',
        'fonts',
        'delete',
        'stash',
      ],
    ],
  },
};

.czrc
{
  "path": "cz-git",
  "messages": {
    "type": "选择你要提交的类型:",
    "scope": "选择一个提交范围(可选):",
    "customScope": "请输入自定义的提交范围:",
    "subject": "填写简短精炼的变更描述:\n",
    "body": "填写更加详细的变更描述(可选)。使用“|”换行:\n",
    "breaking": "列举非兼容性重大的变更(可选)。使用“|”换行:\n",
    "footerPrefixesSelect": "选择关联issue前缀(可选):",
    "customFooterPrefix": "输入自定义issue前缀:",
    "footer": "列举关联issue (可选)例如: #31, #I3244:\n",
    "generatingByAI": "正在通过 AI 生成你的提交简短描述...",
    "generatedSelectByAI": "选择一个 AI 生成的简短描述:",
    "confirmCommit": "是否提交或修改commit?"
  },
  "types": [
    {
      "value": "feat",
      "name": "feat:     ✨  新增功能",
      "emoji": ":sparkles:"
    },
    {
      "value": "fix",
      "name": "fix:      🐛  修复缺陷",
      "emoji": ":bug:"
    },
    {
      "value": "docs",
      "name": "docs:     📚  文档变更",
      "emoji": ":books:"
    },
    {
      "value": "style",
      "name": "style:    💄  代码格式(不影响功能,例如空格、分号等格式修正)",
      "emoji": ":lipstick:"
    },
    {
      "value": "refactor",
      "name": "refactor: 📦  代码重构(不包括 bug 修复、功能新增)",
      "emoji": ":package:"
    },
    {
      "value": "perf",
      "name": "perf:     🚀  性能优化",
      "emoji": ":rocket:"
    },
    {
      "value": "conflict",
      "name": "conflict: 🧰  修改冲突",
      "emoji": ":rewind:"
    },
    {
      "value": "test",
      "name": "test:     ✅  添加疏漏测试或已有测试改动",
      "emoji": ":white_check_mark:"
    },
    {
      "value": "build",
      "name": "build:    🔧  构建流程、外部依赖变更(如升级 npm 包、修改 vite 配置等)",
      "emoji": ":wrench:"
    },
    {
      "value": "ci",
      "name": "ci:       🎡  修改 CI 配置、脚本",
      "emoji": ":ferris_wheel:"
    },
    {
      "value": "revert",
      "name": "revert:   ⏪️  回滚 commit",
      "emoji": ":rewind:"
    },
    {
      "value": "chore",
      "name": "chore:    🔨  对构建过程或辅助工具和库的更改(不影响源文件、测试用例)",
      "emoji": ":hammer:"
    },
    {
      "value": "fonts",
      "name": "fonts:    🔠  字体文件更新",
      "emoji": ":capital_abcd:"
    },
    {
      "value": "delete",
      "name": "delete:   🆑  删除文件",
      "emoji": ":cl:"
    }
  ],
  "useEmoji": true,
  "emojiAlign": "center",
  "useAI": false,
  "aiNumber": 1,
  "themeColorCode": "",
  "scopes": [],
  "allowCustomScopes": true,
  "allowEmptyScopes": true,
  "customScopesAlign": "bottom",
  "customScopesAlias": "custom",
  "emptyScopesAlias": "empty",
  "upperCaseSubject": false,
  "markBreakingChangeMode": false,
  "allowBreakingChanges": [
    "feat",
    "fix"
  ],
  "breaklineNumber": 100,
  "breaklineChar": "|",
  "skipQuestions": [],
  "issuePrefixes": [
    {
      "value": "closed",
      "name": "closed:   ISSUES has been processed"
    }
  ],
  "customIssuePrefixAlign": "top",
  "emptyIssuePrefixAlias": "skip",
  "customIssuePrefixAlias": "custom",
  "allowCustomIssuePrefix": true,
  "allowEmptyIssuePrefix": true,
  "confirmColorize": true,
  "minSubjectLength": 0,
  "defaultBody": "",
  "defaultIssues": "",
  "defaultScope": "",
  "defaultSubject": ""
}
package.json
scripts:  {
    // 开发环境运行项目,会自动读取.env.development配置
    "dev": "vite",
    // 生产环境打包项目到dist目录,会自动读取.env.production
    "build:prod": "vite build",
    // 预发环境打包项目到dist目录,会自动读取.env.staging
    "build:stage": "vite build --mode staging",
    // 在本机跑个server来运行dist目录
    "preview": "vite preview",
    // stylelint检测文件并自动fix
    "stylelint:fix": "stylelint \"src/**/*.{html,vue,css,scss}\" --fix",
    // stylelint检测文件并将错误输出到.stylelint-output.txt
    "stylelint:out": "stylelint \"src/**/*.{html,vue,css,scss}\" -o .stylelint-output.txt -f string",
    // prettier检测文件
    "prettier": "prettier --check  \"src/**/*.{js,ts,json,css,less,scss,vue,html,md}\"",
    // prettier检测文件并自动fix
    "prettier:fix": "prettier --log-level error --write \"src/**/*.{js,ts,json,css,less,scss,vue,html,md}\"",
    // eslint检测文件
    "eslint": "eslint --ext .js,.vue ./src vite.config.js ",
    // eslint检测文件并自动fix
    "eslint:fix": "eslint --ext .js,.vue --fix ./src vite.config.js",
    // eslint检测文件并将错误输出到指定.eslint-ouput.html
    "eslint:out": "eslint --ext .js,.vue -o .eslint-output.html -f html ./src vite.config.js",
    // eslint检测文件并将错误输出到指定.eslint-ouput.html,并且自动修复
    "eslint:fixout": "eslint --ext .js,.vue --fix -o .eslint-output.html -f html ./src vite.config.js",
    // lint-staged 检测git暂存区的文件
    "lint-staged": "lint-staged",
    // 同git commit
    "cm": "git-cz",
    // 一般无需关注
    "commitlint": "commitlint -e -V",
    // husky 初始化
    "prepare": "husky"
  }

git core.autocrlf的设置

不同系统下换行符不同,具体问题可以自行百度,这里不做赘述。具体配置如下

 #windows下输入命令 
 git config --global core.autocrlf true

 #mac下输入命令 
 git config --global core.autocrlf input

 #查看是否设置成功 
 git config --global --get core.autocrlf 

版本依赖

除了eslint,其他依赖包版本皆为当下最新版本。经测试eslint v9与其他依赖包可能会出现兼容性问题,当然也可能是我没有配置正确,暂时未对v9做深入。

"devDependencies": {
    "@commitlint/cli": "^19.2.2",
    "@commitlint/config-conventional": "^19.2.2",
    "commitizen": "^4.3.0",
    "cz-git": "^1.9.1",
    "eslint": "8.57.0",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-import": "^2.29.1",
    "eslint-plugin-prettier": "^5.1.3",
    "eslint-plugin-vue": "^9.25.0",
    "husky": "^9.0.11",
    "lint-staged": "^15.2.2",
    "prettier": "^3.2.5",
    "stylelint": "^16.3.1",
    "stylelint-config-recess-order": "^5.0.1",
    "stylelint-config-recommended-scss": "^14.0.0",
    "stylelint-config-standard": "^36.0.0",
    "stylelint-config-standard-scss": "^13.1.0",
    "stylelint-config-standard-vue": "^1.0.0",
    "vite": "5.0.4",
    "vite-plugin-eslint": "^1.8.1",
  }

注意事项

注意文件的命名的问题,因为我的package.json里指定了type: “module”, 所以.js文件都会当作es module模块被处理。如果你不想以es module的方式来书写配置,你应当以.cjs扩展名来命名配置文件。

  • 16
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值