本文系统梳理前端代码规范,包含以下内容
glob语法(它在前端工程化领域用途很广)prettier格式化工具stylelint样式检查工具eslintJS检查工具prettier + stylelint + eslint 的融合使用及VSCode配置husky + lint-staged commit前对按需检查,commitlint对注释检查CICD 。为什么要说 glob模式匹配 呢,因为本文涉及的代码规范工具如EditorConfig、Eslint、Prettier的配置有它的身影。实际上应该是所有工具只要涉及文件匹配的都是使用它,比如.gitignore、webpack.config.js、 gulpfile.js、 tsconfig.json等。
它与正则表达式用途有本质区别,正则表达式适用更广泛,它只处理文件匹配。因为它的规则更少。
背景:
Unix 系统上的一个名叫 glob 的命令(glob 是 global 的缩写),用于展开命令行中的通配符。C 语言库函数glob(),知名的 shell 解释器就使用了该接口,shell 脚本和命令行中使用的 glob 模式匹配功能便源自于此。| 规则 | 示例 | 匹配 | 不匹配 |
|---|---|---|---|
?匹配单个字符匹配多个字符用多个 ? |
ls ?.txt |
a.txt、b.txt |
aa.txt、.txt |
*表示任意数量的字符 |
ls a*.txt |
a.txt、ab.txt |
b.txt、bb.txt |
[...]匹配方括号之中的任意一个字符 |
ls [ab].txt |
a.txt、b.txt |
c.txt |
[start-end]表示一个连续的范围 |
ls [a-c].txt |
a.txt、b.txt、c.txt |
d.txt |
[^...]不在方括号里面的字符[!...]与[^...]作用完全一样 |
ls [^a].txt |
b.txt、c.txt |
a.txt |
ls [^a-c].txt |
d.txt |
a.txt、b.txt、c.txt |
|
{...}表示匹配大括号里面的所有模式,模式之间使用逗号分隔。 |
echo d{a,e}g |
dag、deg |
dog |
它可以用于多字符的模式。echo {cat,dog} |
cat、dog |
dag |
|
{start..end}会匹配连续范围的字符。 |
echo d{a..c}g |
dag、dbgdcg |
ddg |
| 匹配a文件夹下任意txt文件 | ls a/*.txt |
a/b.txt、a/cc.txt |
- |
| 深度匹配当前文件夹下任意文件 | ls **/* |
f1/f1.txt、f1/f2.txt、f2/b.s、f2/txt、f1/ff/ff1.txt |
- |
{start..end}会匹配连续范围的字符。 |
echo d{a..c}g |
dag、dbgdcg |
ddg |
更多{...}模式

更多{start..end}模式

那么在前端工程化中如何使用glob模式匹配呢?
可使用 node-glob ,它基于 minimatch 和 Node 实现 glob 模式遍历文件的 API。
glob 模式主要用于匹配文件路径regexp 要弱很多。
# 开头的行都会被 Git 忽略/ 开头防止递归/ 结尾指定目录! 取反参考资料:
EditorConfig是用于多人协作使用同编辑器和IDE时,能够保持统一的代码风格webstorm内置了EditorConfig, 一些轻量级工具如VSCode、Subline Text 需要安装插件EditorConfig的匹配非常少,以下是个人推荐的配置示例
ini# 已经是顶层配置文件,不必继续向上搜索
root = true
# 所有文件都必须遵守的规则
[*]
# 编码字符集
charset = utf-8
# 缩进风格是空格
indent_style = space
# 一个缩进占用两个空格,因没有设置tab_with,一个Tab占用2列
indent_size = 2
# 换行符 lf
end_of_line = lf
# 文件以一个空白行结尾
insert_final_newline = true
# 去除行首的任意空白字符
trim_trailing_whitespace = false
# md文件要准守的规则
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false
注意
glob模式匹配Prettier 和 Eslint等工具的配置文件也是 glob模式匹配 ,后续不在强调Prettier是一个固执己见的代码格式化工具,固执己见是指它只有少量选择,它内置了一些规则(无需在代码审查中讨论风格,节省您的时间和精力)js/ts/css/yml/html/md 文件, 其他文件想要支持的话要使用插件看一下Prettier的配置示例
.prettierrc.jsonjson{
"printWidth": "100",
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"arrowParens": "always",
"insertPragma": true,
"proseWrap": "preserve",
"vueIndentScriptAndStyle": false,
"endOfLine": "lf",
"embeddedLanguageFormatting": "auto",
"singleAttributePerLine": false
}
Prettier的配置文件有有很多种方式

关于每个配置项的作用建议前往官网查看(虽然是英文文档,但是有图示一看便懂)
它和EditorConfig有一些功能重叠,但是EditorConfig配置极少, 只要保证endOfLine、useTabs、tabWidth两者一致即可。
还有一点区别是EditorConfig可以作用域所有类型的文件,Prettier作用的文件类型有限
VSCode中使用Prettier需要安装插件, --略VSCode支持使用Prettier为格式化

这时候会在你的项目文件夹下生成.vscode/settings.json文件

这样Command + S 保存就可以使用Prettier自动格式化代码了。
默认只是CSS/JS/HTML/TS文件会使用Prettier格式化, 如果是JSX/TSX/vue文件还需要一步额外操作



eslint,看看它的功能| - | Prettier | eslint |
|---|---|---|
| 功能 | 只关注代码风格 | 关注代码风格和代码质量 |
| 作用时机 | 作用于输入和预览阶段 | 作用于保存阶段 |
| CLI | npx prettier --write . prettier . "!**/*.{js,jsx,vue}" --write | npx eslint --fix . |
| 配置文件 | 支持JSON/JS格式 | 支持JSON/JS/YAML格式 |
| API方式使用 | 支持 | 支持 |
| 忽略文件 | .prettierignore | .eslintignore |
| 禁止区块 | <!-- prettier-ignore-start --> <!-- prettier-ignore-end --> | /*eslint-disable*/ /*eslint-enable*/ |
| 禁止单行 | // prettier-ignore<!-- prettier-ignore --> | // eslint disable// eslint-disable-line no-var/* eslint-disable no-var,space-before-function-paren */ |
关于eslint之前单独写过一篇文章《Eslint深入浅出》
由于Eslint功能包含代码风格和代码质量,而Prettier仅关注代码风格,那么 ESLint 是否可替代 Prettier ?
有以下两点无法取代Prettier
ESLint中的Formatting rules并非都提供了fixerESLint着重于 JS/TS 无法兼容CSS/Markdown/Html
术业有专攻,代码规范方面得交给Prettier既然不能替代,那么两者之间怎么解决冲突?
eslint-plugin-prettier插件增加了prettier/prettier规则,该规则执行prettier并将错误信息上报eslint。简言之,把prettier融合到eslint中,担负起代码检查的功能,同时需要配合搭配eslint-config-prettier关闭调ESLint中代码风格相关的规则。
我尝试写了一个支持前端各种类型(JS/CSS/SCSS/HTML/TS/JSX/TSX)的文件编辑器提示和格式化的脚手架Demo
.editorconfig配置不变,见前面的模板.prettierrc.json 配置不变,见前面的模版..eslintrc.js 内容如下jsmodule.exports = {
env: {
browser: true,
es2021: true,
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:vue/vue3-essential",
"prettier",
],
overrides: [
{
env: {
node: true,
},
files: [".eslintrc.{js,cjs}"],
parserOptions: {
sourceType: "script",
},
},
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
plugins: ["vue", "prettier"],
rules: {
'prettier/prettier': 'error',
},
}
该配置做了以下事情
TS/JSX/TSX/Vue格式的文件Prettier融入Eslint,代码风格交给Prettier处理有些项目不一定使用Prettier,所以还需要研究了下VSCode中使用Eslint自动格式化, 配置方法与前面Prettier格式化类似
总结
Eslint只能格式化 JS/TS/JSX/TSX 文件CSS/SCSS/HTML/Vue等还是需要使用Prettier进行格式化VSCode需要安装Prettier、ESlint、Volar插件(Volar是vue3语法的插件)再次注意: 上述案例有个坑,你会发现使用eslint格式化快捷键,Prettier的规则没有生效。
但是如果使用npx eslint --fix和npx prettier --write格式化同一个文件发现结果一样,说明项目配置没问题。
格式化的文件发现eslint的提示并不对,这说明是 VSCode的ESlint插件问题,翻了很多文档,坑了我几个小时, 终于找到答案, 调整配置如下

这样就可以愉快的玩耍了(其实还有点小问题,由于CommonJS模块的缓存行, 修改Prettier配置需要重新使用VSCode打开项目,但是规范制定好,只要不去改规范就没不会遇到问题)。
stylelint 可以类比 eslint 在JS中的作用,它不仅管代码风格还管代码质量
它将帮助您避免错误,例如:
- 无效的东西,例如定义了
grid-area的无效值- 有疑问的东西,例如重复选择器
- 有问题的东西,例如属性名称拼写错误
并强制执行约定,例如:
- 禁止某些规则,例如具体某个单位
- 强制命名模式,例如对于自定义属性采用短横线
kebab-case规范- 设定限制,例如ID选择器的数量
- 指定符号,例如现代色彩函数
我们建议使用像
Prettier和Stylelint。Linters和Prettier是互补的工具,它们一起工作可以帮助您编写一致且无错误的代码。
贴一张图解释前面的描述

这里先简单总结一下它的功能,有大致的了解。
package.json中的stylelint.stylelintrc文件 JSON格式.stylelintrc.{cjs,js,json,yaml,yml} filestylelint.config.{cjs,mjs,js} filejson{
"rules": {
"color-no-invalid-hex": true
}
}
值类型有以下几种
null 关闭规则[主要选项, 次要选项]json{
"rules": {
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": ["global"]
}
]
}
}
npx stylelint "**/*.css"前面的案例执行效果如下图

.stylelintignore 这里也是glob语法eslint非常像css/* stylelint-disable */
区块屏蔽
/* stylelint-enable */
/* stylelint-disable declaration-no-important */
区块屏蔽
/* stylelint-enable declaration-no-important */
#id {
/* stylelint-disable-line */
color: pink !important;
}
/* ...... */
支持手动编程 参考官网 Node.js API
支持插件、支持PostCSS插件
插件安装不用说了,
按照官方文档写demo,但是没有效果, 坑!折腾了会回找到原因
stylelint-wont-mark-errors-in-vscode
这里贴一下我的配置
.vscode/setting.jsonjson{
"editor.formatOnPaste": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
// 文件保存时开启stylelint自动修复程序
"source.fixAll.stylelint": true
},
// 防止编辑器内置linter与插件冲突设置
"css.validate": false,
"less.validate": false,
"scss.validate": false,
// 启用stylelint插件
"stylelint.enable": true,
"stylelint.config": null,
}
.stylelintrc.jsonjson{
"extends": [
"stylelint-config-standard"
],
"rules": {
"declaration-empty-line-before": "never",
"unit-allowed-list": [
"em",
"rem"
],
"selector-max-id": 1
}
}
stylelint从15版本起(目前最新版本15.0.3)废弃了 所有与代码风格(Prettier干的事情)的配置,专注于CSS的代码质量。
已弃用的风格规则
我们已经废弃了 76 条强制执行风格约定的规则,例如缩进。当我们创建这些规则时,
Prettier还不存在。他们现在提供了一种更好的方法来一致地格式化代码,尤其是空格。Linters和Prettier是互补的工具,它们一起工作可以帮助您编写一致且无错误的代码。通过弃用这些规则,我们可以:
- 专注于编写和维护规则,帮助您避免错误并强制执行(非风格)约定,这两者都是
stylelint所独有的- 使我们的代码库现代化,例如迁移到
ESM,以便我们可以更新依赖项并确保stylelint的安全
如果你用的stylelint< 14 可以参考这篇文章的配置。
这里 我写了一个案例 stylelint + scss + prettier
首先Git支持 自定义钩子 自定义钩子文档
在.git/hooks/这个目录下面
移除sample就可以使用
但实际上并没有这样用的,我推测有以下几点原因
.git文件夹存在于本地,不会提交到远程仓库,你需要写脚本,脚本是使用shell和Perl语言编写,此外shell脚本在window电脑和mac电脑有一些区别。
Git Hook感兴趣,可与读一下这篇文章 《git-pre-commit钩子使用》。commit做全量检查不友好,需要增量检查husky 是一个 Git Hook 工具。husky 其实就是一个为 git 客户端增加 hook 的工具。
husky 有一个快捷命令npx husky-init,一键安装并配置pre-commit hook,它会自动完成以下操作
npm pkg set scripts.prepare="husky install"
package.json文件中增加了一个script脚本npm run prepare
prepare是一个钩子,会在npm install、npm publish、npm pack命令前执行 ,详见官网介绍npm install命令, 触发 npm run prepare, 再触发 husky install,husky 会设置.hasky/为git hooks目录pre-commit的默认脚本你也可以通过node_modules/husky/README.md查看 husky的使用
commitlint 是约束git提交代码时注释的规范。
官方的一张图胜过千言万语
使用步骤
pnpm install --save-dev @commitlint/cli @commitlint/config-conventionalecho "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.jsnpx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'这样就配置完成了, 当执行git commit -m 'XXX'时就会拦截校验你的XXX内容。
如果你提交没有通过, 会提示你怎么写注释, 这里是文档
你还可以自定义规则
使用步骤
pnpm install -D lint-stagedhusky pre-commit 钩子执行脚本.husky/pre-commitsh#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged # 校验
package.jsonjson"lint-staged": {
"src/**/*.{js,ts,vue}": "npx eslint",
"src/**/*.{css,scss,html,vue}": "npx stylelint --allow-empty-input"
}
本段落完整代码案例点这里
参考资料
我写了一个综合案例 github仓库CICD-demo
我们先从package.json梳理流程
json{
"script": {
"lint": "eslint --ext .js,.ts --quiet src --fix && npx lint-staged",
},
"pre-commit": [
"lint"
],
"lint-staged": {
"*.{css,scss,html,md, vue}": [
"prettier --write"
],
"*.{css,scss}": [
"stylelint \"**/*.{css,scss}\""
],
"*.{js,ts}": [
"jest --bail --passWithNoTests --findRelatedTests"
]
}
}
pre-commit是入口,它是git hooks的钩子,在代码提交前检查代码是否符合规范,不符合规范将不可被提交 这里配置了lint 意思是执行 npm run lintnpm run lint 找到 pkg.script.lint对应的命令eslint --ext .js,.ts --quiet src --fix && npx lint-staged
eslint --ext .js,.ts --quiet src --fix 使用eslint格式化src文件夹下面所有后缀为.js、.ts的文件,
--quiet仅报告错误,--fix 自动修复, 当然有些错误如运行时错误是无法自动修复的,失败就退出了, 成功继续执行npx lint-staged 会读取配置即pkg.lint-stagedlint-staged 配置了3条规则
prettier对项目中所有后缀为.css、.scss、.md、.html的文件进行格式化jest对项目中所有后缀为.spec.js、.spec.ts的文件进行单元测试
--bail 执行过程中只要遇到一次错误就退出--passWithNoTests 因为jest默认将没有一个测试用例执行视为错误, 这里告诉jest是正常情况--findRelatedTests 只对有改动的文件进行单元测试网上也有方案将 eslint格式化配置到 lint-staged里面,这样会遇到一个问题
所以把eslint放到了外部
最后推荐一些比较实用的vscode插件
注: 右边为安装插件后的效果
clg回车 => console.log(object);imp回车 => import moduleName from 'module'edf回车 => export default function test(params) {}live-server
会本地启动一个服务,选中html文件右击在浏览器打开
Vue Language Features (Volar) vue3语法插件, vue2使用的是Vetur
Compare Folders 文件夹比较
Color Picker 展示颜色
GitLens
本文作者:郭敬文
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!