工具
EditorConfigESLintJenkins
EditorConfig
在编辑时约束代码风格,在IDE中如:WebStorm格式化时(command+shift+f)将按照配置中的规则进行格式化。官方文档:https://editorconfig.org/,一份规则示例:
# top-most EditorConfig file
root = true
[*]
Unix-style newlines with a newline ending every file
end_of_line = lf
[*.{js,py}]
# 字符编码集
charset = utf-8
# 缩进使用 tab 或者 space
indent_style = space
# 缩进为space时缩进字符数
indent_size = 2
# 是否将尾行空格自动删除
trim_trailing_whitespace = true
# 是否使文件以一个空白行结尾
insert_final_newline = true
# 编码区字符数(宽度)限定 结合eslint max-len WebStorm支持 VSCode不支持
max_line_length = 100
# 引号样式 single double auto
quote_type = single
# 花括号是否另起一行
#curly_bracket_next_line = true
# 操作符两边是否有空格 true false hybrid
spaces_around_operators = true
# 括号两边是否有空格 none inside outside both
#spaces_around_brackets = both
WebStorm默认支持EditorConfig,其它IDE可能需要下载插件支持,WebStorm下导出.editorconfig,Perferences->CodeStyle->EditorConfig如下:

ESLint
插件化的javascript代码检测工具。官方文档:https://cn.eslint.org/
安装ESLint
npm install -g eslint
初始化
eslint -- init
这里我们选择问答方式生成初始化的eslint配置文件

选择完成后ESLint会根据选择的配置下载相关的插件,如我们选择使用了React
在
package.json中就有eslint-plugin-react包,相关依赖下载完成后在项目根目录下会生成.eslintrc.json(或.eslintrc.js根据你选择的配置)文件
-
.eslintrc.json文件
{
"env": {
"node": true,
"browser": true,
"es6": true
},
"parser": "babel-eslint",
"plugins": [
"react"
],
"extends": "standard",
"rules": {
"react/jsx-uses-vars": 2,
"camelcase":0
}
}
文档配置详情说明 https://cn.eslint.org/docs/user-guide/configuring
parser
"parser": "babel-eslint"
解析器可能的配置有Esprima Babel-ESLint typescript-eslint-parser
extends
"extends": "standard"
extends决定了ESLint使用何种配置插件进行代码检查,如:
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
"plugins": [
"react"
]
就是启用ESLint推荐规则和React推荐规则,插件eslint-plugin-react及其规则说明,extends其它值可以有:airbnb,eslint:recommended,eslint:all
"extends": "airbnb", // airbnb eslint:recommended standard eslint:all
-
airbnb相关说明
英文-https://github.com/airbnb/javascript
中文-https://github.com/yuche/javascript
airbnb的rule相比较于eslint:recommended启用了eslint标记为不推荐的规则,因此,编码规范要求就要更高一些。
npm -i eslint-config-airbnb --save-dev
同时会下载相关依赖插件eslint-plugin-import, eslint-plugin-jsx-a11y,eslint-plugin-react,启用对React和jsx的一些规则检查
插件eslint-plugin-import及其规则说明
插件eslint-plugin-react及其规则说明
插件eslint-plugin-jsx-a11y及其规则说明
-
rules
ESLint 附带有大量的规则。你可以使用注释或配置文件修改你项目中要使用的规则。要改变一个规则设置,你必须将规则 ID 设置为下列值之一:
"off" 或 0 - 关闭规则
"warn" 或 1 - 开启规则,使用警告级别的错误:warn(不会导致程序退出)
"error" 或 2 - 开启规则,使用错误级别的错误:error(当被触发的时候,程序会退出)
如下一个简单示例:
"rules": {
"quotes": [
"error",
"single"
], //强制单引号
"camelcase":2 //强制驼峰
}
命令行执行检查扫描
由于ESLint我是本地安装的(--save-dev)需要切换到node_modules目录下执行,目录结构(React-Native项目)

node_modules/.bin/eslint src index.js
扫描src目录以及根目录下的index.js文件,扫描结算后我们在命令行会看到如下结果:

Jenkins
在命令行中生成的结果,不方便定位与查看,这里通过Jekins做持续集成对项目进行规范化管理。
-
package.json
编辑package.json增加lint命令支持
"scripts": {
"lint": "node_modules/.bin/eslint --ext .js src index.js -c .eslintrc.json -f checkstyle > eslint.xml",
"start": "node node_modules/react-native/local-cli/cli.js start"
}
--ext .js src index.js 表示扫描/src目录下扩展名为.js的文件 以及根目录下的index.js文件
-c .eslintrc.json 表示选择根目录下的.eslintrc.json文件作为扫描的配置文件
-f checkstyle >eslint.xml将扫描结果以checkstyle方式输出报告,输出到根目录下的eslint.xml
eslint命令详情-官方文档
-
配置工程与选择分支
image.png -
配置submodule
由于node_modules以sub-modules添加到了工程源码库管理,需要拉取子module
image.png -
添加构建脚本
image.png
切换到library(node_modules)目录拉取目标分支最新代码,再切换回根目录执行lint命令。
-
添加构建后步骤
将构建结果以Checkstyle results的形式输出,选择CheckStyle需要Jenkins插件支持。
image.png - 查看结果
image.png
查看整个项目的扫描结果,根据需要浏览具体代码,选择或者禁用某些规则,然后重新编辑.eslintrc.json文件生成一份适用于自己团队的规则文件。
eslint配置示例(基于airbnb规范)
-
array-bracket-spacing强制数组方括号中使用一致的空格2 -
array-callback-return强制数组方法的回调函数中有 return 语句0 -
arrow-body-style要求箭头函数体使用大括号1 -
arrow-parens要求箭头函数的参数使用圆括号0 -
brace-style强制在代码块中使用一致的大括号风格2 -
camelcase强制使用骆驼拼写法命名约定2 -
class-methods-use-this强制类方法使用 this1 -
comma-dangle要求或禁止末尾逗号
"comma-dangle": [1, {
"objects": "always",
"imports": "never",
"arrays": "never",
"exports": "never",
"functions": "never"
}]
-
consistent-return要求 return 语句要么总是指定返回的值,要么不指定2 -
default-case要求 switch 语句中有 default 分支0 -
dot-notation强制尽可能地使用点号2 -
eol-last要求或禁止文件末尾存在空行2 -
eqeqeq要求使用 === 和 !==2 -
func-names要求或禁止使用命名的 function 表达式2 -
function-paren-newline强制在函数括号内使用一致的换行2 -
global-require要求 require() 出现在顶层模块作用域中0 -
guard-for-in要求 for-in 循环中有一个 if 语句1 -
import/first将全部import写在模块开始的位置0 -
import/newline-after-importimprot结束后应有空行2 -
import/no-duplicates禁止重复导入相同文件2 -
import/no-extraneous-dependencies禁止导入未在包中声明的外部模块2 -
import/no-mutable-exports可导出对象禁止用let或者var修饰 ->const2 -
import/no-unresolved确保导入的模块可以被解析为本地文件系统上的模块0 -
import/prefer-default-export当从模块中只导出单个出口时使用默认导出1 -
indent缩进风格
"indent": [
"error",
2,
{"SwitchCase": 1} // set 1 -> 2 spaces; set 2 -> 4 spaces
]
-
jsx-quotes强制在 JSX 属性中一致地使用双引号或单引号2prefer-single -
linebreak-style强制使用一致的换行风格2lf
"linebreak-style": [
"error",
"unix"
]
-
max-len强制一行的最大长度 1001
"max-len": [
"warn",
100
]
-
newline-per-chained-call要求方法链中每个调用都有一个换行符2 -
no-bitwise禁用按位运算符1 -
no-case-declarations不允许在 case 子句中使用词法声明2 -
no-confusing-arrow禁止在可能与比较操作符相混淆的地方使用箭头函数2 -
no-continue禁用 continue 语句1 -
no-else-return禁止 if 语句中 return 语句之后有 else 块2 -
no-empty禁止出现空语句块2 -
no-extend-native禁止扩展原生类型2exceptions Date
"no-extend-native": [
"error",
{"exceptions": ["Date"]}
]
-
no-extra-semi禁止不必要的分号2 -
no-lonely-if禁止 if 作为唯一的语句出现在 else 语句中2 -
no-loop-func禁止在循环中出现 function 声明和表达式1 -
no-mixed-operators禁止混合使用不同的操作符0 -
no-mixed-spaces-and-tabs禁止空格和 tab 的混合缩进2 -
no-multi-assign禁止连续赋值2 -
no-nested-ternary禁用嵌套的三元表达式2 -
no-param-reassign禁止对 function 的参数进行重新赋值2 -
no-plusplus禁用一元操作符 ++ 和 --0 -
no-prototype-builtins禁止直接调用 Object.prototypes 的内置属性2 -
no-restricted-globals禁用特定的全局变量2 -
no-restricted-properties禁止使用对象的某些属性1 -
no-restricted-syntax禁用特定的语法 使用for-each map for-i2 -
no-shadow禁止变量声明与外层作用域的变量同名2 -
no-tabs禁用 tab2 -
no-trailing-spaces禁用行尾空格2 -
no-undef禁用未声明的变量,除非它们在 /*global */ 注释中被提到2 -
no-underscore-dangle禁止标识符中有悬空下划线0 -
no-unreachable禁止在return、throw、continue 和 break 语句之后出现不可达代码2 -
no-unused-expressions禁止出现未使用过的表达式2allowShortCircuit true
"no-unused-expressions": ["error", {"allowShortCircuit": true}]
-
no-unused-vars禁止出现未使用过的变量2 -
no-use-before-define禁止在变量定义之前使用它们2 -
no-useless-concat禁止不必要的字符串字面量或模板字面量的连接0 -
no-useless-constructor禁用不必要的构造函数2 -
no-useless-escape禁用不必要的转义字符0 -
no-var要求使用 let 或 const 而不是 var2 -
object-curly-newline强制大括号内换行符的一致性2 -
object-curly-spacing强制在大括号中使用一致的空格2 -
object-shorthand要求或禁止对象字面量中方法和属性使用简写语法2 -
one-var强制函数中的变量要么一起声明要么分开声明0 -
one-var-declaration-per-line要求或禁止在变量声明周围换行0 -
operator-assignment要求或禁止在可能的情况下使用简化的赋值操作符1 -
padded-blocks要求或禁止块内填充2class always
"padded-blocks": [
"error", {"classes": "always"}
]
-
prefer-arrow-callback要求回调函数使用箭头函数2 -
prefer-const要求使用 const 声明那些声明后不再被修改的变量2 -
prefer-destructuring优先使用数组和对象解构2object
"prefer-destructuring": [
"error", {"array": false, "object": true}
]
-
prefer-rest-params要求使用剩余参数而不是 arguments2 -
prefer-spread要求使用扩展运算符而非 .apply()2 -
prefer-template要求使用模板字面量而非字符串连接2 -
quote-props要求对象字面量属性名称用引号括起来2 -
quotes强制使用一致的反勾号、双引号或单引号2
"quotes": [
"error",
"single"
]
-
radix强制在parseInt()使用基数参数0 -
react/forbid-prop-types禁止某些propTypes1 -
react/jsx-boolean-value在JSX中强制布尔属性符号2 -
react/jsx-closing-bracket-location在JSX中验证右括号位置1 -
react/jsx-closing-tag-location在JSX中验证右标签位置2 -
react/jsx-curly-brace-presence在JSX中启用或者禁用不必要的大括号 props always children never
"react/jsx-curly-brace-presence": [
"error",
{"props": "always", "children": "never"}
]
-
react/jsx-curly-spacing在JSX属性和表达式中加强或禁止大括号内的空格 禁止2 -
react/jsx-equals-spacing在JSX属性中强制或禁止等号周围的空格 禁止2 -
react/jsx-filename-extension限制包含JSX的文件扩展名0 -
react/jsx-first-prop-new-line属性强制换行2 -
react/jsx-indentjsx中缩进检查2 -
react/jsx-indent-propsjsx中属性缩进检查2 -
react/jsx-max-props-per-line限制JSX中单行上的props的最大数量2 -
react/jsx-no-bindJSX中不允许使用箭头函数和bind2 -
react/jsx-no-duplicate-props防止在JSX中重复的props2 -
react/jsx-tag-spacingJSX中开起标签开始和结束空格检查2 -
react/jsx-wrap-multilines多行JSX中避免丢失括号2 -
react/no-array-index-key防止在数组中遍历中使用数组key做索引2 -
react/no-did-mount-set-state防止在componentDidMount中使用setState2 -
react/no-multi-comp防止每个文件有多个组件定义2 -
react/no-unescaped-entities防止无效字符出现在标记中1 -
react/no-unused-prop-types避免定义未使用的PropType, defined but never used1 -
react/no-unused-state避免定义未使用的state2 -
react/prefer-stateless-function无状态管理(stateless)的React组件应该继承PureComponent1 -
react/prop-types防止在React组件定义中丢失props验证(类型验证)1 -
react/require-default-props非require的props需在defaultProps中申明1 -
react/self-closing-comp防止没有children的组件的额外结束标签<Text></Text>2 -
react/sort-comp强制组件方法顺序2
① static methods and proper
② lifecycle methods
③ custom methods
④ render method
-
semi要求或禁止使用分号2禁止分号
"semi": [
"error", "never"
]
-
space-before-function-paren强制在 function的左括号之前使用一致的空格2 -
spaced-comment强制在注释中 // 或 /\ 使用一致的空格2 -
switch-colon-spacing强制在 switch 的冒号左右有空格2 -
vars-on-top要求所有的 var 声明出现在它们所在的作用域顶部2 -
no-console: 禁止使用console0





