一、 在React+Babel+Webpack环境中使用ESLint
- ESLint是js中目前比较流行的插件化的静态代码检测工具。通过使用它可以保证高质量的代码,尽量减少和提早发现一些错误。使用eslint可以在工程中保证一致的代码风格,特别是当工程变得越来越大、越来越多的人参与进来时,需要加强一些最佳实践。
- 本文假设您已经有一个react+babel+webpack的起始工程,可以 参考react-webapp-startkit
- 首先,安装eslint包 在项目的跟目录下,运行
npm --save-dev install eslint
因为我们使用了webpack,所以必须要告诉webpack我们在构建时使用eslint,安装eslint-loader
- 安装之后,我们可以再webpack配置中使用eslint加载器了。 webpack.config.js
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'react-hot!babel'
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader'
}
]
},
此外,我们既可以在webpack配置文件中指定检测规则,也可以遵循最佳实践在一个专门的文件中指定检测规则。我们就采用后面的方式。
在根目录下:
touch .eslintrc
.eslintrc
{
"rules": {
}
}
稍后我们可以在该文件中指定规则,但首先我们要在Webpack配置文件中引入该文件。
webpack.cofnig.js
...
devServer: {
contentBase: './dist',
hot: true,
historyApiFallback: true
},
eslint: {
configFile: './.eslintrc'
},
plugins: [
...
现在可以启动app了,在根目录下
npm run dev // 取决与package.json中的定义
你可能会看到The keyword ‘import’ is reserved的解析错误。这是因为eslint还不知道通过Babel使用的ES6特性(比如import)。 ESLint + Babel 之前,我们已经安装了babel-loader(在起步工程中)来转换我们的代码。现在我们可以将它和eslint-loader一同使用。
webpack.config.js
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'react-hot!babel'
},
{
test: /\.js$/,
exclude: /node_modules/,
loaders: ['babel-loader', 'eslint-loader']
}
]
},
或者,使用webpack的preLoaders
...
module: {
preLoaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader'
},
],
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'react-hot!babel'
}
]
},
...
我们可以通过 babel-eslint来检测ES6代码。
还是先安装
npm install --save-dev babel-eslint
修改.eslintrc
{
parser: "babel-eslint",
"rules": {
}
}
现在应该可以启动app了,但是没有任何错误显示,不要高兴的太早,这只是因为我们还没有添加任何检测规则。 ESLint规则 我们来添加我们的第一条规则。
修改.eslintrc
...
"rules": {
"max-len": [1, 70, 2, {ignoreComments: true}]
}
...
我们添加了一条规则来检查代码的单行长度,当单行代码长度大于70个字符时,检测会报错。
启动app,你可能会看到关于代码长度的错误,因为某些行多于70个字符了。我们可以修改规则来允许更多的字符。
.eslintrc
...
"rules": {
"max-len": [1, 120, 2, {ignoreComments: true}]
}
...
如果还有错误,可能你就需要考虑修改代码了。
React的ESLint规则 现在来添加一些检测React的代码规则,使用eslint-plugin-react。
npm --save-dev install eslint-plugin-react
安装之后,我们可以使用react插件来指定我们关于react的第一条代码规则。比如我们要求组件指定PropTypes。
.eslintrc
{
parser: "babel-eslint",
"plugins": [
"react"
],
"rules": {
"max-len": [1, 120, 2, {ignoreComments: true}],
"prop-types": [2]
}
}
当启动app后,你可能会看到PropTypes定义的错误,你可能想要修复这些错误。
另外,我们可以使用一些包含推荐规则的预设,但暂时我们先扩展自己的规则。
扩展ESLint规则 我们不想每次都指定这些规则,所幸已经有很多符合最佳实践的规则。其中之一就是Airbnb Style Guide,此外Airbnb还开源了他们自己的ESlint配置。
已经有一部分依赖包安装了,但还缺少一些:
npm --save-dev install eslint-config-airbnb eslint-plugin-import eslint-plugin-jsx-a11y
Now we can add a one-liner to our ESLint configuration to use Airbnbs’ ESLint configuration. When you look back at the packages we installed, you can see that the configuration includes JSX and React rules.
接下来,通过一行代码的配置来让我们可以使用Airbnb的ESLint配置(你可以通过查看node_modules里面的包来查看,这个配置包含了jsx和React的规则)
.eslintrc
{
parser: "babel-eslint",
"extends": "airbnb",
"rules": {
"max-len": [1, 120, 2, {ignoreComments: true}],
"prop-types": [2]
}
}
我们可以看到可以很简单的使用别人的配置规则来扩展ESLint规则。我们还可以使用其他的扩展,但目前Airbnb代码规范和ESlint配置非常的受欢迎并被大多数开发者所接受。
微调 有时候,为了迎合自己的项目需要,需要对某些特殊的规则微调。 比如我们不想看到no-unused-vars(为使用过的变量定义)的警告,可以
.eslintrc
{
parser: "babel-eslint",
"extends": "airbnb",
"rules": {
"no-unused-vars": 0,
"max-len": [1, 120, 2, {ignoreComments: true}],
"prop-types": [2]
}
}
上面这种是全局的配置,如果是只想在某些文件中禁止检测,可以如下修改(通过注释的方式)
src/index
/*eslint-disable no-unused-vars*/
import SC from 'soundcloud';
/*eslint-enable no-unused-vars*/
import React from 'react';
import ReactDOM from ‘react-dom';
...
pre-commit钩子 如果项目使用了git,可以通过使用pre-commit钩子在每次提交前检测,如果检测失败则禁止提交。可以在很大一定程度上保证代码质量。
这里我们使用了pre-commitgit包来帮助我们实现这一目标。
首先在package.json中添加script命令:
"scripts": {
"eslint": "eslint --ext .js src"
}
其次,安装pre-commit
npm install pre-commit --save-dev
最后,在package.json中配置pre-commit需要运行的命令:
"pre-commit": [
"eslint"
]
完成之后,在每次提交之前,都会运行eslint命令进行检测,如果检测到有违反代码规则的情况,则会返回1,导致git commit失败。
done.
二、详解React开发必不可少的eslint配置
Eslint介绍
Eslint 是一个JavaScript验证工具,有了它可以让你的编辑器像ide一样进行一些静态的错误提示功能. 安装eslint
- $ npm install eslint -g 项目需要安装的插件
"babel-eslint": "^8.0.3",
"eslint": "^4.13.1",
"eslint-plugin-react": "^7.5.1",
配置详情 下面的配置涵盖了开发者所需要的绝大部分信息,rules中的值0、1、2分别表示不开启检查、警告、错误。你可以看到下面有些是0,如果有需要开启检查,可以自己修改为1或者2。
module.exports = {
"env": {
"browser": true,
"commonjs": true,
"es6": true
},
"extends": "eslint:recommended",
"globals": {
"$": true,
"process": true,
"__dirname": true
},
"parser": "babel-eslint",
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true
},
"sourceType": "module",
"ecmaVersion": 7
},
"plugins": [
"react"
],
"rules": {
"quotes": [2, "single"], //单引号
"no-console": 0, //不禁用console
"no-debugger": 2, //禁用debugger
"no-var": 0, //对var警告
"semi": 0, //不强制使用分号
"no-irregular-whitespace": 0, //不规则的空白不允许
"no-trailing-spaces": 1, //一行结束后面有空格就发出警告
"eol-last": 0, //文件以单一的换行符结束
"no-unused-vars": [2, {"vars": "all", "args": "after-used"}], //不能有声明后未被使用的变量或参数
"no-underscore-dangle": 0, //标识符不能以_开头或结尾
"no-alert": 2, //禁止使用alert confirm prompt
"no-lone-blocks": 0, //禁止不必要的嵌套块
"no-class-assign": 2, //禁止给类赋值
"no-cond-assign": 2, //禁止在条件表达式中使用赋值语句
"no-const-assign": 2, //禁止修改const声明的变量
"no-delete-var": 2, //不能对var声明的变量使用delete操作符
"no-dupe-keys": 2, //在创建对象字面量时不允许键重复
"no-duplicate-case": 2, //switch中的case标签不能重复
"no-dupe-args": 2, //函数参数不能重复
"no-empty": 2, //块语句中的内容不能为空
"no-func-assign": 2, //禁止重复的函数声明
"no-invalid-this": 0, //禁止无效的this,只能用在构造器,类,对象字面量
"no-redeclare": 2, //禁止重复声明变量
"no-spaced-func": 2, //函数调用时 函数名与()之间不能有空格
"no-this-before-super": 0, //在调用super()之前不能使用this或super
"no-undef": 2, //不能有未定义的变量
"no-use-before-define": 2, //未定义前不能使用
"camelcase": 0, //强制驼峰法命名
"jsx-quotes": [2, "prefer-double"], //强制在JSX属性(jsx-quotes)中一致使用双引号
"react/display-name": 0, //防止在React组件定义中丢失displayName
"react/forbid-prop-types": [2, {"forbid": ["any"]}], //禁止某些propTypes
"react/jsx-boolean-value": 2, //在JSX中强制布尔属性符号
"react/jsx-closing-bracket-location": 1, //在JSX中验证右括号位置
"react/jsx-curly-spacing": [2, {"when": "never", "children": true}], //在JSX属性和表达式中加强或禁止大括号内的空格。
"react/jsx-indent-props": [2, 4], //验证JSX中的props缩进
"react/jsx-key": 2, //在数组或迭代器中验证JSX具有key属性
"react/jsx-max-props-per-line": [1, {"maximum": 1}], // 限制JSX中单行上的props的最大数量
"react/jsx-no-bind": 0, //JSX中不允许使用箭头函数和bind
"react/jsx-no-duplicate-props": 2, //防止在JSX中重复的props
"react/jsx-no-literals": 0, //防止使用未包装的JSX字符串
"react/jsx-no-undef": 1, //在JSX中禁止未声明的变量
"react/jsx-pascal-case": 0, //为用户定义的JSX组件强制使用PascalCase
"react/jsx-sort-props": 2, //强化props按字母排序
"react/jsx-uses-react": 1, //防止反应被错误地标记为未使用
"react/jsx-uses-vars": 2, //防止在JSX中使用的变量被错误地标记为未使用
"react/no-danger": 0, //防止使用危险的JSX属性
"react/no-did-mount-set-state": 0, //防止在componentDidMount中使用setState
"react/no-did-update-set-state": 1, //防止在componentDidUpdate中使用setState
"react/no-direct-mutation-state": 2, //防止this.state的直接变异
"react/no-multi-comp": 2, //防止每个文件有多个组件定义
"react/no-set-state": 0, //防止使用setState
"react/no-unknown-property": 2, //防止使用未知的DOM属性
"react/prefer-es6-class": 2, //为React组件强制执行ES5或ES6类
"react/prop-types": 0, //防止在React组件定义中丢失props验证
"react/react-in-jsx-scope": 2, //使用JSX时防止丢失React
"react/self-closing-comp": 0, //防止没有children的组件的额外结束标签
"react/sort-comp": 2, //强制组件方法顺序
"no-extra-boolean-cast": 0, //禁止不必要的bool转换
"react/no-array-index-key": 0, //防止在数组中遍历中使用数组key做索引
"react/no-deprecated": 1, //不使用弃用的方法
"react/jsx-equals-spacing": 2, //在JSX属性中强制或禁止等号周围的空格
"no-unreachable": 1, //不能有无法执行的代码
"comma-dangle": 2, //对象字面量项尾不能有逗号
"no-mixed-spaces-and-tabs": 0, //禁止混用tab和空格
"prefer-arrow-callback": 0, //比较喜欢箭头回调
"arrow-parens": 0, //箭头函数用小括号括起来
"arrow-spacing": 0 //=>的前/后括号
},
"settings": {
"import/ignore": [
"node_modules"
]
}
};
,你还希望看到更多的react检查器,那就去 eslint-plugin-react 的github文档去慢慢翻译吧。
某些文件关闭eslint检查 你不总是希望所有的文件都开启eslint检查,那么,给单独的js文件关闭eslint的方式,只需要在该文件的最顶部加上一段注释。
/*eslint-disable*/
function test() {
return true
}
给某一行js代码关闭eslint检查 关闭整个js文件的行为有点暴力,别担心,你还可以只给其中某段代码关闭eslint。
// eslint-disable-next-line
alert('foo')
eslint配置文件类型 eslint配置文件类型不只有js和json,其实包括下面这些:
.eslintrc.js
.eslintrc.yaml
.eslintrc.yml
.eslintrc.json
.eslintrc
package.json