规范化是我们践行前端工程化中的重要一部分。主要说说为什么要有规范化标准、哪些地方需要规范化、如何实施规范化。
为什么有标准
软件开发需要多人协同,但是不同的人会有各自的开发喜好和习惯,如果同一项目不做规范约束,没有统一的标准则会增加项目维护成本,所以每个项目或团队都需要有明确统一的规范化标准。
哪里需要规范化
一般来说只要是人为编写的成果物都需要规范化,比如代码、文档、提交日志。代码的标准化是最重要的,因为它决定了代码质量和可维护性。
实施规范化的方法
最初比较简单,就是在编码前进行人为的进行标准约定,在code review环节根据约定去进行检查,但这样的方式效率太低,也不全面,不可靠,开发人员也不能记住所有的规范。
所以就出现了Lint工具,配合自动化工具还可以自动检查。Lint名称是起源于C语言的编译前的一款叫Lint的检查工具。
ESLint介绍
它是最为主流的JavaScript Lint工具,用来检测代码的质量和规范,通过它可以很容易去统一编码规范。同时它还可以去检测代码中很多潜在不合理的地方,比如使用未定义变量、声明变量前使用、两等符号,帮我们提高代码质量。通过规范的约束,ESLint也可以帮助开发者提高编码能力。
开始使用
梳理一下操作步骤:
- 初始化项目
- 安装ESLint模块为开发依赖
- 通过CLI命令验证开发结果
安装、配置ESLint
yarn add eslint --dev // 安装
yarn eslint --init // 初始化eslint配置文件
yarn eslint 文件路径 // 校验文件,可以写为通配符形式
ESLint的env属性
详细属性表和说明如下表所示,并且在env属性中可以配置多项。
ESLint的extend属性
用于继承一些公共的配置,接收一个数组。使用它需要遵守对应的语法规则,内部元素可以直接定义包名,也可以按照plugin形式定义插件包下导出的公共配置。比如:
extends: [
'plugin:react/recommended', // 公共配置
'standard'
],
ESLint的configs属性
用于定义公共的规则配置,在外部可以通过plugin:插件名/配置名的方式进行继承。
{
configs: {
recommended: {
plugins: [
'react'
],
parserOptions: {
ecmaFeatures: {
jsx: true
}
},
rules: {
'react/display-name': 2,
'react/jsx-key': 2,
}
},
all: {
plugins: [
'react'
],
parserOptions: {
ecmaFeatures: {
jsx: true
}
},
rules: activeRulesConfig
},
'jsx-runtime': {
plugins: [
'react'
],
parserOptions: {
ecmaFeatures: {
jsx: true
}
},
rules: {
'react/react-in-jsx-scope': 0,
'react/jsx-uses-react': 0
}
}
}
}
ESLint的parserOptions属性
设置语法解析器的相关配置,主要是控制使用哪个版本的ES语法标准。并且env所配置的语法标准优先级是高于该属性的。
ESLint的rules属性
配置ESLint中各种语法校验的规则:是否开启;配置校验选项;以及以何种形式进行报错,可选属性为:off、warn、error。
// 展示部分配置示例
{
"rules": {
"no-var": "warn",
"accessor-pairs": ["error", { "setWithoutGet": true, "enforceForClassMembers": true }],
"array-bracket-spacing": ["error", "never"],
"array-callback-return": ["error", {
"allowImplicit": false,
"checkForEach": false
}],
"arrow-spacing": ["error", { "before": true, "after": true }]
}
}
ESLint的globals属性
额外的声明在代码中可访问的全局成员:
{
globals: {
'jQuery': 'readonly'
}
}
ESLint的plugins属性
接受一个数组,用于配置eslint相关插件,比如eslint-plugin-react。在extend中如果继承了对应的配置,就不必要在这重复配置了。
ESLint的paser属性
配置语法解析器,在ts项目中能使用到:
parser: '@typescript-eslint/parser'
配置注释
在一般的开发过程中,代码肯定存在某些情况不能使用所配置的规范,我们也不能因为这些情况去更改我们的整个规范配置,所以就要用到配置注释,它可以将某行或某个文件的规范失效掉,从而不会报出规范检查错误。
// eslint-disable-line
直接注释失效整行代码
// eslint-disable-line no-template-curly-in-string
可以指定失效更具体的规范配置
// eslint-disable-line no-template-curly-in-string, quotes
禁用多个规范配置
以上所说属性,更详细的配置可以去官方文档上去查看。
ESLint结合Gulp
首先需要在项目中安装eslint、eslint-gulp两个依赖模块,然后通过yarn eslint --init初始化一份ESLint配置。在将所有依赖都下下来后,在gulpfile.js文件中对ESLint进行配置,我们仅在处理JS的任务中加入ESLint插件:
// gulpfile.js
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(plugins.eslint()) // 配置插件
.pipe(plugins.eslint.format()) // 负责打印错误信息
.pipe(plugins.eslint.failAfterError()) // 检查到错误信息终止任务管道
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true }))
}
我们需要在管道最开始的地方配置eslint插件,不然经过babel转化后,就不是原始的代码了。
这里发现最新版本eslint-config-standard和eslint-gulp是不兼容的,解决方法是要去除es2021这个关键字,并且发现降低版本到14.1.1好像也没有用。
ESLint结合Webpack
Webpack结合ESlint检查,是通过loader机制,而不是plugin机制。接入的方式也和Gulp差不多,首先安装好eslint、eslint-loader等依赖,然后初始化一个.eslintrc.js文件,继续安装对应的eslint依赖,然后在webpack.config.js文件中配置eslint。
module: {
rules: [
// 方式一
{
test: /.js$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader'],
},
// 方式二
{
enforce: 'pre',
test: /.js$/,
exclude: /node_modules/,
loader: 'eslint-loader'
},
]
}
enforce配置为pre是为了在第一个使用该loader,详细解释可以查看官方文档。
在webpack中,eslint结合happypack的场景,会发生reduce undefined报错,最终发现解决办法是需要在happypack的插件配置中加入loaders属性,在这定义要用到的loader
现代化项目集成ESLint
随着前端React、Vue框架的普及,它们的生态已经非常好了。这里以Vue来举例,在这里可以直接使用vue-cli来生成一个Vue项目,我们手动进行交互配置,这里有一条问题值得注意,说的是何时使用lint进行检查:
Lint on save // 在webpack监视模式下,每当监听到文件修改,就触发一次lint
Lint and fix on commit // 这里是配合git hook,在git提交前进行lint并且fix修复
TypeScript结合ESLint
使用eslint直接初始化
StyleLint介绍
对于css代码一般使用StyleLint进行规范检查,它提供了:
- 默认的代码检查规则
- CLI工具,可以快速调用
- 通过插件,可支持Less、Sass、PostCss等衍生css语法的检查
- 支持Gulp和Webpack集成
使用方法:
将stylelint作为开发依赖安装到项目中,针对Less、Sass、PostCss安装不同的插件进行支持:
- stylelint-config-sass-guidelines
- stylelint-config-standard
配置.styleintrc.js文件来配置语法检查规则:
module.exports = {
extends: ["stylelint-config-standard", "stylelint-config-sass-guidelines"]
}
可以关注下Less相关插件,StyleLint集成入webpack、Gulp,以及HTML等的Lint工具。
HTML Lint工具有这么些:Bootlint、AriaLinter、htmllint、HTMLHint 及htmlcs。
配合Webpack、Gulp:我们可以使用stylelint-webpack-plugin插件配合Webpack,使用gulp-stylelint配合Gulp,Npm文档链接:gulp-stylelint、stylelint-webpack-plugin
stylelint的stylelint-config-standard插件,已支持对less的语法检查
Prettier
前端代码规范化工具。
使用方法:
- 将prettier作为开发依赖在项目中进行安装
- 通过
yarn prettier ./style.css --write将格式化后代码写入文件中 - 通过
yarn prettier . --write格式化文件目录下所有文件
Git Hooks
团队开发中,开发成员可能忘记进行Lint,那么可以使用Git Hooks在代码提交前进行强制的Lint操作。以下是关于它的相关介绍:
- Git Hook也称之为git钩子,每个钩子对应一个任务
- 通过shell脚本可以编写钩子任务触发时要具体执行的操作
在每一个git仓库中,都会有一个.git文件夹,它里边就有git hook的示例,我们可以基于它去编写:
简单的说,GitHooks就是通过钩子来对应具体的Git操作,当这个操作执行时就自动的执行钩子内定义的任务。但是对于Shell脚本很多前端开发人员并不会写,所以有了Husky这个简化工具,实现对Git Hooks的需求。
husky的功能会有些短板,配合lint-staged工具可以补足它的不足。