前端工程项目规范化

在 vite、openapi 项目中使用 eslint与prettier与stylelint与husky的详细指南

参考文档

vue3组件库开发之项目初始化
前端根据openapi+swagger生成接口方法
openApi 配置详情
在 vue3 、ts、vite 项目中使用 eslint与prettier与stylelint与husky的详细指南
Vue3 + Ts + Vite + pnpm 项目中集成 —— eslint 、prettier、stylelint、husky、commitizen
前端项目工程化规范

创建项目

这里以vue项目为例

pnpm create vite my-vue-app --template vue-ts

为什么需要eslint与prettier 本文主要以实战为主,这里就不过多赘述eslint与prettier的作用了,不清晰的同学可以查阅一下相关资料。简单来说,就是eslint可以保证项目的质量,prettier可以保证项目的统一格式、风格

配置eslint

pnpm add eslint -D
pnpm eslint --init

一路安装后 会生成一下 配置文件 .eslintrc.js

如果打开生成的配置文件 出现module is not defined 等错误的话。 就在.eslintrc.js env 配置项 添加一个 node: true
在package.json文件中的script中添加lint命令 后运行 pnpm run lint

{
    "scripts": {
        "lint:eslint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix"
    }
}

如果 运行后出现 Parsing error > excepted等错误 ,说明 @typescript-eslint/parser把vue-eslint-parser覆盖了。 需要单独增加一个配置项用于格式化 vue文件 "parser": "vue-eslint-parser" 2、"root": true 是为了避免运行时出现警告
一下是.eslintrc.cjs 的完整配置。

module.exports = {
   "env": {
       "browser": true,
       "es2021": true,
       "node": true
   },
   "extends": [
       "eslint:recommended",
       "plugin:vue/vue3-essential",
       "plugin:@typescript-eslint/recommended"
   ],
   "parser": "vue-eslint-parser",
   "parserOptions": {
       "ecmaVersion": "latest",
       "parser": "@typescript-eslint/parser",
       "sourceType": "module"
   },
   "plugins": [
       "vue",
       "@typescript-eslint"
   ],
   "root": true,
   "rules": {
   }
}

配置prettier

pnpm add prettier -D

.prettierrc.js配置文件如下

module.exports = {
    // 一行的字符数,如果超过会进行换行,默认为80
    printWidth: 80, 
    // 一个tab代表几个空格数,默认为80
    tabWidth: 2, 
    // 是否使用tab进行缩进,默认为false,表示用空格进行缩减
    useTabs: false, 
    // 字符串是否使用单引号,默认为false,使用双引号
    singleQuote: true, 
    // 行位是否使用分号,默认为true
    semi: false, 
    // 是否使用尾逗号,有三个可选值"<none|es5|all>"
    trailingComma: "none", 
    // 对象大括号直接是否有空格,默认为true,效果:{ foo: bar }
    bracketSpacing: true
}

在package.json中的script中添加以下命令

{
    "scripts": {
        "lint:prettier": "prettier --write \"./**/*.{html,vue,ts,js,json,md}\"",
    }
}

在根目录下新建.prettierrc.js 如果你的文件建立错了就会报错 如下

可以尝试以下几种解决方法:

  • 将 .prettierrc.js 文件重命名为 .prettierrc.cjs,以明确指示该文件为 CommonJS 模块。
  • 修改引用该文件的代码,使用动态 import()。这种方法适用于所有的 CommonJS 模块。
  • 在 package.json 中将 "type": "module" 修改为 "type": "commonjs",以将所有的 .js 文件都视为 CommonJS 模块。如果需要使用 ES 模块,则可以使用 .mjs 文件扩展名。
  • 升级到 Prettier 2.3.2 或更高版本,该版本已经支持 .prettierrc.js 文件的 ES 模块语法。

解决eslint与prettier的冲突

pnpm add eslint-config-prettier eslint-plugin-prettier -D

在 .eslintrc.cjs 中extends的最后添加一个配置

{ 
    extends: [
    'eslint:recommended',
    'plugin:vue/vue3-essential',
    'plugin:@typescript-eslint/recommended',
    // 新增,必须放在最后面
    'plugin:prettier/recommended' 
  ],
}

如果写一行代码就要执行一遍lint命令,这效率就太低了。所以我们可以配合vscode的ESLint插件,实现每次保存代码时,自动执行lint命令来修复代码的错误。在项目中新建.vscode/settings.json文件,然后在其中加入以下配置

{
  "editor.codeActionsOnSave": {
    "source.fixAll": false,
    "source.fixAll.eslint": true,
    "source.fixAll.stylelint": true
  },
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "stylelint.validate": ["scss", "css", "vue", "html"]
}

配置stylelint

stylelint 为css的lint工具。可格式化css代码,检查css语法错误与不合理的写法,指定css书写顺序等.
less

pnpm add stylelint postcss postcss-less postcss-html stylelint-config-prettier stylelint-config-recommended-less stylelint-config-standard stylelint-config-standard-vue stylelint-less stylelint-order -D

scss

pnpm add stylelint postcss postcss-scss postcss-html stylelint-config-prettier stylelint-config-recommended-scss stylelint-config-standard stylelint-config-standard-vue stylelint-scss stylelint-order -D

增加.stylelintrc.cjs配置文件

module.exports = {
  extends: [
    'stylelint-config-standard',
    'stylelint-config-prettier',
    'stylelint-config-recommended-scss',
    'stylelint-config-standard-vue'
  ],
  plugins: ['stylelint-order'],
  // 不同格式的文件指定自定义语法
  overrides: [
    {
      files: ['**/*.(less|css|vue|html)'],
      customSyntax: 'postcss-less'
    },
    {
      files: ['**/*.(html|vue)'],
      customSyntax: 'postcss-html'
    }
  ],
  ignoreFiles: [
    '**/*.js',
    '**/*.jsx',
    '**/*.tsx',
    '**/*.ts',
    '**/*.json',
    '**/*.md',
    '**/*.yaml'
  ],
  rules: {
    'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
    'selector-pseudo-element-no-unknown': [
      true,
      {
        ignorePseudoElements: ['v-deep']
      }
    ],
    'selector-pseudo-class-no-unknown': [
      true,
      {
        ignorePseudoClasses: ['deep']
      }
    ],
    // 指定样式的排序
    'order/properties-order': [
      'position',
      'top',
      'right',
      'bottom',
      'left',
      'z-index',
      'display',
      'justify-content',
      'align-items',
      'float',
      'clear',
      'overflow',
      'overflow-x',
      'overflow-y',
      'padding',
      'padding-top',
      'padding-right',
      'padding-bottom',
      'padding-left',
      'margin',
      'margin-top',
      'margin-right',
      'margin-bottom',
      'margin-left',
      'width',
      'min-width',
      'max-width',
      'height',
      'min-height',
      'max-height',
      'font-size',
      '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',
      'opacity',
      'filter',
      'list-style',
      'outline',
      'visibility',
      'box-shadow',
      'text-shadow',
      'resize',
      'transition'
    ]
  }
}

package.json增加命令

"scripts": {
    "prepare": "husky install",
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "preview": "vite preview",
    "lint:eslint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix",
    "lint:prettier": "prettier --write \"./**/*.{html,vue,ts,js,json,md}\"",
    "lint:stylelint": "stylelint \"./**/*.{css,less,scss,vue}\" --fix"
},

配置husky

在介绍 husky 之前,首先要理解什么是 hook(钩子),在前端 Vue 框架中提供了 beforCreated、created、beforeMounted、mounted 等函数、这些函数都是钩子,也常被称为‘生命周期钩子函数’,它们会在 Vue 实例化过程中有序地执行。
在 Git 中也存在一些钩子,其中较常用的有 pre-push、pre-commit 、commit-msg,其中 pre-commit 钩子会在 commit 前触发,pre-push 会在 push 前触发。(提示:所有钩子默认情况下是禁用的)
这些钩子可以用来干嘛?
比方我们可以利用pre-commit 钩子在 commit 时对代码先进行 eslint 检查,如果不合格就不给 commit,
不过使用 git 钩子稍微麻烦,于是就有了 husky ,它能让我们使用 git 钩子变得更加容易。

pnpm add husky -D
npx husky install
npx husky add .husky/pre-commit
npx husky add .husky/commit-msg

在package.json中的script中添加一条脚本命令

{
    "scripts": {
        "prepare": "husky install"
    },
}

该命令会在pnpm install之后运行,这样其他克隆该项目的同学就在装包的时候就会自动执行该命令来安装husky。这里我们就不重新执行pnpm install了,直接执行pnpm prepare,这个时候你会发现多了一个.husky目录。
然后使用husky命令添加pre-commit钩子,运行

pnpm husky add .husky/pre-commit "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint"

配置git规范

pnpm add cz-conventional-changelog 

在package.json文件中添加以下配置:

{
	"scripts": {
		"commit": "git pull && git add -A && git-cz && git push"
	},
	"config": {
		"commitizen": {
			"path": "./node_modules/cz-conventional-changelog"
		}
	}
}

保证提交合规 全局安装

pnpm add -g commitizen cz-conventional-changelog
posted @ 2023-06-01 18:01  boygdm  阅读(46)  评论(0编辑  收藏  举报