前言
工欲善其事,必先利其器。 —— 《论语》
具体到写代码则是需求一套趁手的东西和完整的作业流程,简略讲便是代码产出标准以及主动帮我们进行标准约束的东西
准备
新建项目文件夹,新增index.js
写入以下内容
alert('test')
console.log('test')
eval()
进入文件夹终端,履行以下指令
npm i -g pnpm
pnpm init
一致包管理器
在 package.json
的 scripts
项添加 preinstall
钩子约束项目运用的包管理器,如 npx only-allow pnpm -y
约束运用 pnpm
关于 scripts
钩子能够参阅官网文档,对 only-allow
感兴趣的能够看这篇剖析:only-allow 源码学习
"scripts": {
"preinstall": "npx only-allow pnpm -y"
}
ESlint
装置 eslint
pnpm i -D eslint
新增 .eslintrc
文件,写入以下 rules
{
// rules 取值 0、1、2,分别是不处理、正告、制止
"rules": {
"no-eval": 2,
"no-alert": 1, // 制止运用alert confirm prompt
"no-console": 0
}
}
履行 pnpm eslint "**/*.js"
,得到以下校验成果
1:1 warning Unexpected alert no-alert
3:1 error eval can be harmful no-eval
✖ 2 problems (1 error, 1 warning)
Typescript 支撑
pnpm i -D typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin
新增 main.ts
文件,输入以下内容
const toString = Object.prototype.toString
export function is(val: unknown, type: any): boolean {
return toString.call(val) === `[object ${type}]`
}
alert('test')
console.log('s')
eval('')
.eslintrc
修正如下
{
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/no-explicit-any": 2,// 禁用any
"no-eval": 2,
"no-alert": 1, // 制止运用alert confirm prompt
"no-console": 0
}
}
履行 pnpm eslint "**/*.ts"
得到以下校验成果
2:40 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
5:1 warning Unexpected alert no-alert
7:1 error eval can be harmful no-eval
✖ 3 problems (2 errors, 1 warning)
从上面的比方能够看到 ESLint
仍是挺容易装备的,为了便利后面装备,先来了解一些常用装备项
常用装备详解
具体阐明请参阅 ESLint 装备
parser 和 parserOptions 解析器及其装备
parser
作为主解析器运用,parserOptions
则是针对解析器的一些补充装备,如parserOptions.parser
则能够装备子解析器,也能够针对不同类型文件装备不同的解析器
以 .vue
文件来举例,运用 vue-eslint-parser
进行解析,文件内不同的内容再运用不同解析器
{
"parser": "vue-eslint-parser",
"parserOptions": {
"parser": {
"js": "espree",
"ts": "@typescript-eslint/parser",
"<template>": "espree",
}
}
}
有些库因其内部做了处理只需求装备 parser
即可,比方parser
指定为 @typescript-eslint/parser
也能够处理 js
,比方前面的比方在装备 Typescript
支撑后履行 pnpm eslint "**/*.js"
指令相同能够得到检测成果
parserOptions.project
由于项目中或许会运用别号(resolve.alias
)或许有其特殊装备,所以需求指定对应装备才干正确解析
比方下面的装备 @typescript-eslint/parser
解析器会依据 project
指定的 tsconfig.json
的装备对 ts
进行解析,这样对于 ts
文件内途径别号 @
才干正确解析其途径
// .eslintrc
"plugins": ["@typescript-eslint"],
"parserOptions": {
"parser": "@typescript-eslint/parser",
"project": "./tsconfig.json"
},
// tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src"],
"exclude": ["node_modules"]
}
还有一些常用的 parserOptions
装备如 ecmaVersion
指定依照哪个 ecma
版别标准对js
解析, sourceType
用来指定依照哪种模块标准解析js
模块
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
}
extends 和 plugins
不想自己装备繁琐的规矩能够运用 extends
去承继对应插件的规矩,extends
能够是字符串也能够是字符串数组,关于ESLint
是如何解析和运用extends
字段的能够参看源码applyExtends
以 eslint:
最初的如 eslint:recommended
表示运用 eslint
引荐规矩,也有无前缀的如 extends: "airbnb"
,这是承继 eslint-config-airbnb规矩的意思
以 plugin:
最初的则表示运用插件拓宽规矩,如 plugin:jsdoc/recommended
表示运用 jsdoc
插件的引荐规矩
需求自定义规矩或许extends
对应规矩时一般来讲需求装备对应 plugins
以拓宽规矩,插件名称能够省略eslint-plugin-
前缀
假如 rules
或许extends
装备了插件的规矩而 plugins
没指定对应插件,触发 lint
时或许会因读取不到对应规矩而提示失败。
以 eslint-plugin-jsdoc 为例
pnpm i -D eslint-plugin-jsdoc
.eslintrc
修正如下
{
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"extends": [
"plugin:jsdoc/recommended"
],
"rules": {
"no-eval": 2,
"no-alert": 1, // 制止运用alert confirm prompt
"no-console": 0,
"@typescript-eslint/no-explicit-any": 2
}
}
履行 pnpm eslint "**/*.ts"
得到校验成果能够看到看到 jsdoc
的规矩提示
2:8 warning Missing JSDoc comment jsdoc/require-jsdoc
2:40 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
5:1 warning Unexpected alert no-alert
7:1 error eval can be harmful no-eval
✖ 4 problems (2 errors, 2 warnings)
0 errors and 1 warning potentially fixable with the `--fix` option.
不过这儿有个小细节便是 plugins
装备项没有装备jsdoc
对应的插件只装备了extends
,这是plugins
机制,主动加载以eslint-plugin-
为前缀的插件
overrides
overrides
经过 files
能够指定不同文件或文件夹进行针对性装备,且其具有和根底装备项简直相同的装备,如parserOptions
、extends
、plugins
举个比方,比方只针对utils.ts
设置禁用 any
,main.ts
不约束,utils.ts
内容和main.ts
相同
.eslintrc
修正如下
{
"parser": "@typescript-eslint/parser",
"overrides": [
{
"files": [
"utils.ts"
],
"extends": [
"plugin:jsdoc/recommended"
],
"rules": {
"@typescript-eslint/no-explicit-any": 2,
"no-alert": 1
}
}
],
"plugins": [
"@typescript-eslint"
],
"rules": {
"no-eval": 2,
"no-alert": 1
}
}
履行 pnpm eslint "**/*.ts"
成果如下
// main.ts
5:1 warning Unexpected alert no-alert
7:1 error eval can be harmful no-eval
// utils.ts
2:8 warning Missing JSDoc comment jsdoc/require-jsdoc
2:40 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
5:1 warning Unexpected alert no-alert
7:1 error eval can be harmful no-eval
✖ 6 problems (3 errors, 3 warnings)
0 errors and 1 warning potentially fixable with the `--fix` option.
在 utils.ts
正确书写才干经过校验,jsdoc 文档
/**
* 类型检测
*
* @param {any} val 检测目标
* @param {string} type 类型
* @returns {boolean} 是否属于 type 类型
*/
export function is(val: unknown, type: string): boolean {
return toString.call(val) === `[object ${type}]`
}
rules
rules
有多种写法
- 单取数字值: 0、1、2,分别是封闭、正告、制止
- 字符串:”off”、”warn”、”error”和上面0、1、2对应
- 数组,第一项可取前两种取值,第二项为该规矩的具体装备,不同规矩或许支撑不同拓宽写法,更新具体阐明请参照ESlint rules 文档以及对应规矩阐明
"rules": {
"no-alert": 1,
"quotes": ["error", "double"],
"no-console": [
"error", {
"allow": ["log", "warn", "error", "info"]
}
],
}
globals
有时或许需求一些全局变量的设置以处理
"globals": {
"__DEV__": false,
"__dirname": false,
"define": true,
"history": true,
"location": true,
"wxjs": true,
"$": true,
"WeixinJSBridge": true,
"wx": true,
"process": true,
"qq": true
},
别的 ESLint
还供给 .eslintignore
文件用来屏蔽不需求校验的文件
Stylelint
Stylelint
的装备和 ESLint
实际上是一个思路,这儿就不具体介绍了,具体的请参照Stylelint 文档
css
pnpm i -D stylelint stylelint-config-standard
新增index.css
,新增 .stylelintrc
文件,写入以下装备
{
"extends": [
"stylelint-config-standard"
],
"rules": {
"no-empty-first-line": true
}
}
履行 pnpm stylelint "**/*.css"
得到校验成果
index.css
1:1 ✖ Unexpected empty source no-empty-source
1 problem (1 error, 0 warnings)
Scss & Less
pnpm i -D stylelint-scss stylelint-config-recommended-scss
pnpm i -D stylelint-less stylelint-config-recommended-less
.stylelintrc
文件添加 overrides
装备
{
"extends": ["stylelint-config-standard"],
"overrides": [
{
"extends": "stylelint-config-recommended-scss",
"files": ["**/*.scss"]
},
{
"extends": "stylelint-config-recommended-less",
"files": ["**/*.less"]
}
],
"rules": {
"no-empty-first-line": true
},
}
分别树立对应文件履行pnpm stylelint "**/*.{css,scss,less}"
得到以下成果
When linting something other than CSS, you should install an appropriate syntax, e.g. "postcss-less", and use the "customSyntax" option
index.css
1:1 ✖ Unexpected empty source no-empty-source
index.less
1:1 ✖ Unexpected empty source no-empty-source
index.scss
1:1 ✖ Unexpected empty source no-empty-source
3 problems (3 errors, 0 warnings)
提示 less
需求在装备项customSyntax
装备postcss-less
转化器
装置postcss-less
并更改装备如下
{
"extends": [
"stylelint-config-standard"
],
"overrides": [
{
"extends": "stylelint-config-recommended-scss",
"files": [
"**/*.scss"
]
},
{
"extends": "stylelint-config-recommended-less",
"customSyntax": "postcss-less",
"files": [
"**/*.less"
]
}
],
"rules": {
"no-empty-first-line": true
}
}
再次履行 pnpm stylelint "**/*.{css,scss,less}"
关于customSyntax
的装备提示消失
customSyntax
是自定义css
语法转化插件的装备,比方 scss
也有 postcss-scss
,具体阐明参照customSyntax 文档
stylelint-config-recess-order
stylelint
的标准引荐加上主动排序规矩stylelint-config-recess-order
pnpm i -D stylelint-config-recess-order
.stylelintrc
更改如下
{
"extends": ["stylelint-config-standard", "stylelint-config-recess-order"],
"overrides": [
{
"extends": ["stylelint-config-recommended-scss", "stylelint-config-recess-order"],
"files": ["**/*.scss"]
},
{
"extends": ["stylelint-config-recommended-less", "stylelint-config-recess-order"],
"customSyntax": "postcss-less",
"files": ["**/*.less"]
}
],
"rules": {
"no-empty-first-line": true
}
}
从这儿的装备能够看到 overrides
里每一项的 extends
需求单独装备完整的承继关系
和ESLint
相同,Stylelint
供给 .stylelintignore
文件用来屏蔽不需求校验的文件
prettier
ESLint
和 Stylelint
是对js
和css
进行语法标准,代码风格则能够交给prettier来处理
pnpm i -D prettier eslint-config-prettier eslint-plugin-prettier
新增 .prettierrc
文件
{
"printWidth": 140,
"singleQuote": true,
"semi": false,
"trailingComma": "none",
"bracketSameLine": true,
"arrowParens": "avoid",
"htmlWhitespaceSensitivity": "ignore",
"overrides": [
{
// rc 文件依照 json进行格式化
"files": [".prettierrc", ".eslintrc", ".stylelintrc", ".lintstagedrc"],
"options": { "parser": "json" }
}
]
}
prettier
相同供给 .prettierignore
文件用来屏蔽不需求格式化的文件
VScode 装备
当然以上各种 Lint
手动校验真实太累,为了便利能够合作编辑器设置主动格式化,以 VScode
为例
装置对应插件
Prettier - Code formatter
ESLint
Stylelint
-
Vetur
(vue2) Vue Language Features (Volar)
-
TypeScript Vue Plugin (Volar)
(假如运用Vue3 + TypeScript
开发 )
新增 .vscode
文件夹,创建 settings.json
装备文件,写入如下简略装备
留意: eslint.workingDirectories 装备项最好指定当时项目的eslint装备文件,这样编辑器的eslint才会依据项目装备进行校验提示
{
"extensions.ignoreRecommendations": false,
"editor.tabSize": 2,
"typescript.updateImportsOnFileMove.enabled": "always",
"javascript.updateImportsOnFileMove.enabled": "always",
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
"editor.fontSize": 14,
"editor.formatOnType": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[vue]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"prettier.semi": false, //结尾分号
"prettier.trailingComma": "none", //结尾逗号
"prettier.singleQuote": true,
"stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"],
"eslint.workingDirectories": [".eslintrc", { "mode": "location" }],// 这儿需求指定下 .eslintrc ,让编辑器的eslint依据装备去履行校验提示
"eslint.validate": ["vue", "typescript", "javascript", "javascriptreact"]
}
Vue
在 vue
生态链中供给了eslint-plugin-vue库,eslint-plugin-vue 官网 也有具体装备阐明,依据阐明这儿直接挑选 vue-eslint-parser
pnpm i -D vue-eslint-parser eslint-plugin-vue
.eslintrc
在 overrides
装备中添加对应 vue
的装备
{
"parser": "vue-eslint-parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"ecmaFeatures": {"jsx": true }
},
"plugins": ["@typescript-eslint"],
"extends": ["prettier"],
"overrides": [
{
"files": ["**/*.{ts,tsx}"],
"extends": ["plugin:jsdoc/recommended"],
"parserOptions": {
"sourceType": "module",
"parser": "@typescript-eslint/parser"
},
"rules": {
"@typescript-eslint/no-explicit-any": 2,
"no-alert": 1
}
},
{
"files": "**/*.vue",
"extends": ["plugin:vue/vue3-recommended", "prettier"],
"rules": {
"@typescript-eslint/no-explicit-any": 2,
"no-alert": 2
},
"parserOptions": {
"sourceType": "module",
"parser": "@typescript-eslint/parser"
}
}
],
"rules": {
"no-eval": 2,
"no-alert": 1
}
}
留意:履行pnpm eslint **/*.vue
进行测验,装备没错的情况下假如有 Failed to load plugin xxx … Class extends 之类的报错大概率是版别兼容问题
目前 stylelint
是 14.x 版别,在 vue3
的 .vue
文件中有 Unknown word (CssSyntaxError)
过错,解决计划
-
stylelint
降级到 13 版别以下 ,可是相关的插件都需求处理,相对麻烦 - 添加 stylelint-config-html插件来处理
第二种计划比较简略,装置相应插件
pnpm i -D postcss-html stylelint-config-html
.stylelintrc
新增 overrides
装备
{
"extends": [
"stylelint-config-standard",
"stylelint-config-recommended-less",
"stylelint-config-recommended-scss",
"stylelint-config-html/vue",
"stylelint-config-recess-order"
],
"customSyntax": "postcss-html",
"files": [
"**/*.vue"
]
}
这儿直接装备 less
和 scss
支撑,如不需求都支撑只需把extends
中对应的规矩删去即可
vue
有许多社区模板能够参阅
React
既然 Vue
的装备搞懂了 React
的自然不在话下,所以就不再介绍了,参照React ESLint 插件文档、eslint-plugin-react
装备即可
css-in-js
相关的,如styled-component对应的 lint
有
- stylelint-processor-styled-components(已弃用)
- eslint-plugin-styled-components-a11y
- eslint-plugin-styled-components-css
标准代码提交
代码提交也是很重要的一环,这个环节主要是保证提交上来的代码是契合标准的,包含前文装备的lint
标准、提交日志标准、测验用例等,为此需求定制git hooks
在代码提交上来之前处理好
lint-staged
lint-staged能够来处理不同文件类型需求履行的lint
或其他指令
pnpm i -D lint-staged
package.json
中添加lint-staged
内容,比方下面针对 less
等项目文件的格式化和标准处理
"lint-staged": {
"**/*.less": "stylelint --syntax less",
"(**|!__test__)/*.{jsx,js,tsx,ts,less,md,json,vue}": [
"prettier --write",
"git add"
]
},
也能够运用 .lintstagedrc
文件来装备,如
{
"/src/**/*.{js,jsx,ts,tsx,vue}": ["eslint --cache --fix", "prettier --write"],
"/src/**/*.{css,scss,less}": ["stylelint --cache --fix", "prettier --write"],
"**/*.md": "prettier --write"
}
commitlint
标准提交日志对问题定位和代码回滚有较大的含义
首先当时项目未初始化 git
的先履行 git init
初始化 git
commitizen
运用commitizen、cz-conventional-changelog来标准日志格式
# 全局装置 commitizen,或许需求依据过错提示履行 pnpm setup ,需重新加载终端或编辑器
pnpm i -g commitizen
# 初始化 cz,会在 package.json 生成commitizen的装备
commitizen init cz-conventional-changelog --pnpm --save-dev --save-exact
# 需求中文的添加 cz-conventional-changelog-zh
pnpm i -D cz-conventional-changelog-zh
commitizen init cz-conventional-changelog --pnpm --save-dev --save-exact
会在 package.json
生成如下装备
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
运用cz-conventional-changelog-zh
的将path
改为./node_modules/cz-conventional-changelog-zh
即可
履行 git cz
会有如下提示(这儿运用了中文包),依据提示挑选、输入内容即可
? 挑选您要提交的更改类型: (Use arrow keys)
> feat: 一个新功能
fix: 一个bug
docs: 文档增修改
style: 样式修正(空白、格式、短少分号等)
refactor: 既不修复bug也不添加新功能的更改
perf: 功能优化
test: 添加测验
(Move up and down to reveal more choices)
自定义提交标准
新增 commitizen
装备文件 .cz-config.js
-
一种计划是运用 cz-customizable 来改造
.cz-config.js
,支撑的装备项可参阅cz-customizable/cz-config-EXAMPLE.js -
别的一种计划是自己完成一个规矩插件
这儿讲讲自完成方式,新增 commit-rules.js
写入自定义规矩如下
var configLoader = require('commitizen').configLoader;
const types = [
{
"key": "new-type",
"description": "新类型",
"title": "new-type"
},
{
"key": "feat",
"description": "一个新功能",
"title": "Features"
},
{
"key": "fix",
"description": "一个bug",
"title": "Bug Fixes"
},
]
var config = configLoader.load() || {};
/**
* 交互收集 commit 信息插件
*
* @param cz 供给根底的交互才能
* @param commit 适当于 git commit
*/
function prompter (cz, commit) {
var length = types.length
var defaultType = process.env.CZ_TYPE || config.defaultType
var defaultScope = process.env.CZ_SCOPE || config.defaultScope
var choices = types.map(function ({ key, description }) {
return {
name: (key + ':').padEnd(length) + ' ' + description,
value: key
};
});
cz.prompt([
{
type: 'list',
name: 'type',
message: '挑选您要提交的更改类型:',
choices: choices,
default: defaultType
},
{
type: 'input',
name: 'scope',
message: '这个变化的规模是什么(例如组件或文件名):(按回车键越过)',
default: defaultScope,
filter: function (value) {
return value.trim();
}
},
{
type: 'maxlength-input',
name: 'subject',
message: '写一个简短的修正描述(最多20个字符):\n',
maxLength: 20,
validate: function (subject, answers) {
return subject.length == 0
? '短少修正描述'
: subject.length <= 20
? true
: '描述内容的长度必须小于或等于20'
},
}
]).then(answers => {
const { type, scope, subject } = answers
var messageScope = scope ? '(' + scope + ')' : '';
const message = `${type}${messageScope}: ${subject} time: ${new Date().getTime()}`
commit(message)
})
}
module.exports = {
prompter
}
.cz-config.js
写入如下内容
{
"path": "./commit-rules"
}
别的项目或许要求只需求本地装置即可,这样 git cz
指令就无法运用,能够换成当时项目内装置commitizen
, package.json
新增 scripts
"scripts": {
"am": "git add . & git-cz",
"cm": "git-cz"
},
履行 pnpm am
得到自定义规矩交互提示
> git add . & git-cz
cz-cli@4.3.0, t@1.0.0
? 挑选您要提交的更改类型: (Use arrow keys)
> new-type: 新类型
feat: 一个新功能
fix: 一个bug
运用 git cz
或 pnpm git-cz
替代 git commit
用来生成契合标准的 Commit message
husky
然后便是定制git hooks
流程,在 .git/hooks
目录下已经有许多钩子的比方,只需去掉 .sample
后缀钩子便可生效
当然运用 husky 则便利很多
# 装置 husky
pnpm i -D husky
# 未初始化git的需求先初始化git,不然husky会初始化失败
git init
# 初始化husky
pnpm husky install
# 新增钩子文件
npx husky add .husky/pre-commit
npx husky add .husky/commit-msg
commit-msg
文件写入以下内容
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# 校验经过交互收集到的 commit 是否契合标准
pnpm commitlint --edit $1
新增 commitlint.config.js
写入如下内容,由于前面自定义标准的时候格式改动规矩需求相应变动,不然会不经过
module.exports = {
"extends": ['@commitlint/config-conventional'],
"rules": {
'subject-empty': [0, 'never'],
'type-empty': [0, 'never'],
"type-enum": [
2,
"always",
[
"new-type"
]
]
}
}
此刻履行 pnpm am
依据交互提示最终经过自定义规矩能够提交成功
pre-commit
能够参阅如下内容
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# 履行 postinstall 钩子
pnpm run postinstall
# 校验lint
npx lint-staged
# 履行测验用例
pnpm test
最终是测验lint-staged
先把pre-commit
内暂时不存在的指令或钩子移除,履行 pnpm am
,会看到触发了 lint-staged
脚本对文件进行了校验,有些不需求检验的文件能够在.eslintignore
、.stylelintignore
、.prettierignore
添加屏蔽装备或许完善lint-staged
匹配规矩即可
到此根本过完了一切标准拟定和东西集成装备,仍是适当繁琐的,尤其是各种插件的拼装或许会有各种不可思议的报错(大概率是版别问题)
严厉仍是宽松,如何挑选?
有了整个架子就能够依照标准需求去设置对应规矩了,至于一个项目要装备多严厉的标准,我觉得这要看团队的共识,总的来说有以下两个方向
最终挑选感觉主要仍是看leader的情绪。
还有些更严厉的会装备进webpack
等开发东西中时时影响开发过程,个人认为那是在添堵
附录
- 参阅
- npm 文档 #Scripts
- ESlint 文档
- ESLint 装备
- ESlint Rules
- typescript-eslint
- eslint-plugin-jsdoc
- jsdoc 文档
- Stylelint 文档
- prettier
- eslint-plugin-vue 官网
- commitizen
- cz-conventional-changelog
- 阮一峰 Commit message 和 Change log 编写指南
- lint-staged
- husky
- 或许需求的
ESlint
拓宽插件- eslint-config-standard
- eslint-plugin-import
- eslint-plugin-n
- eslint-plugin-promise
- eslint-plugin-react-native
- 本文运用的各种包的版别参照
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.49.0",
"@typescript-eslint/parser": "^5.49.0",
"cz-conventional-changelog": "^3.3.0",
"cz-conventional-changelog-zh": "^0.0.2",
"eslint": "^8.32.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-jsdoc": "^39.6.8",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.9.0",
"husky": "^8.0.3",
"lint-staged": "^13.1.0",
"postcss-html": "^1.5.0",
"postcss-less": "^6.0.0",
"prettier": "^2.8.3",
"stylelint": "^14.16.1",
"stylelint-config-html": "^1.1.0",
"stylelint-config-recess-order": "^3.1.0",
"stylelint-config-recommended-less": "^1.0.4",
"stylelint-config-recommended-scss": "^8.0.0",
"stylelint-config-standard": "^29.0.0",
"stylelint-less": "^1.0.6",
"stylelint-scss": "^4.3.0",
"typescript": "^4.9.4",
"vue-eslint-parser": "^9.1.0"
},
"dependencies": {
"vue": "^3.2.45"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog-zh"
}
}