1.Eslint是用来干嘛的
ESLint最初是由Nicholas C. Zakas 于2013年6月创建的开源项目。它的目标是提供一个插件化的javascript代码检测工具。
2.为什么要使用Eslint
ESLint 是一个开源的 JavaScript 代码检查工具,。代码检查是一种静态的分析,常用于寻找有问题的模式或者代码,并且不依赖于具体的编码风格。对大多数编程语言来说都会有代码检查,一般来说编译程序会内置检查工具。
代码千万行,安全第一行;前端不规范,同事两行泪
- 统一团队编码规范(命名,众多格式等)
- 统一语法,毕竟es版本已经不少了(var/let…)
- 减少git不必要的提交(如果文件格式不一样,也会被git提交的)
- 避免低级错误 在编译时检查语法,而不是等JS引擎运行时才检查
3.手动下载配置(原理)
3.1 创建项目
创建一个测试文件夹:eslint_test
初始化项目:npm init -y (创建 package.json)
3.2 ESLint安装
直接在项目中安装eslint包 npm i eslint -D
注意安装结果:node_moduels
中下载了很多包
-
.bin/eslint.cmd 脚本文件,内部通过 nodejs 执行 eslint运行包 的代码
-
@eslint包 用来规范eslint配置文件
-
eslint开头的包 是 eslint运行包,包含eslint代码
3.3 生成ESLint配置文件
使用 npx 来执行 (推荐):npx eslint --init
执行结果
3.6 ESLint执行 -
命令:npx eslint ./需要检查语法的文件路径
-
如果违法规范,会将错误提示到 终端,说明 eslint 工作正常
4.ESLint配置文件入门
4.1 env节点
"env": {
"browser": true,
"commonjs": true,
"es2021": true
}
由于 ESLint 的各种规范中,一般都不允许使用未在页面内声明的成员,所以告诉eslint,当前代码运行在那些环境中。
4.2 globals节点
当访问当前源文件内未定义的变量时,no-undef 规则将发出警告。如果你想在一个源文件里使用全局变量,推荐你在 ESLint 中定义这些全局变量,这样 ESLint 就不会发出警告了。你可以使用注释或在配置文件中定义全局变量。
"globals": {
"_": true // 可以读取,可以修改
"$": false // 可以读取,不能修改
}
可以使用 globals 节点来手动配置全局成员
4.3 extends 节点
通过这个节点可以配置使用 内置规范 还是 第三方规范
"extends": [
"standard" // "eslint-config-standard"
]
注意:配置 extends时,可以省略 eslint-config-,直接写成 standard
4.4 parserOptions 节点
ESLint 解析器 解析代码时,可以指定 用哪个 js 的版本
"parserOptions": {
"ecmaVersion": 12
}
注意:这里是指定 检查时按照哪个js版本语法检查,但这里不包含 全局变量
4.5 rules 节点
"rules": {
}
两种用法:
- 不使用 extend 节点 配置 整套的规范,而是在 rules节点中直接配置
- 使用 extend 节点 配置 整套的规范,在 rules节点中修改部分规范的配置
5.ESLint检查语法的规则
5.1 ESLint语法规范本质
本质就是函数
我们可以通过 看 ESLint 源码查看:
- eslint 内置285个规则,每条规则 都是一个 create函数
- 在进行语法检查时,会将代码转成另一种
6. 语法规范包类型
a. ESLint内置规范包 :eslint-all / eslint-recommended
b. 标准规范包:eslint-config-standard
c. 第三方规范包(google/airbnb/facebook…)
6.1 内置规范包
已经随eslint一起下载:
eslint-all
:使用全部280多个规则
eslint-recommended
:只使用推荐的60个规则
6.2 标准规范包(需要下载)
包名:eslint-config-standard
也使用了200多个规则
手动下载:
a. 查看需要下载的包和版本 npm info "eslint-config-airbnb-base@latest" peerDependencies
b.下载 相关包 npx install-peerdeps --dev eslint-config-airbnb-base
7. 配置规范包
7.1 修改 eslint 配置文件
module.exports = {
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
// "extends": "eslint:all", // 内置:所有规则
// "extends": "eslint:recommended", // 内置:推荐规则
"extends": "eslint-config-standard", // 第三方:标准规则
// "extends": "eslint-config-airbnb-base", // 第三方:airbnb公司规则
"parserOptions": {
"ecmaVersion": 12
},
"rules": {
}
};
7.2 运行ESLint
注意:ESLint 默认只检查 js 文件代码,如果想 检查 vue 或 react文件,需要装其它插件包
npx eslint ./index.js // 检查 目标文件
npx eslint ./src // 检查 目标文件夹 中所有js文件
7.3 测试不同包检查相同代码
一段相同代码
注意:自己平时写代码还是要开启严格模式,要是去公司还得按照公司规范书写。
下面是我个人在项目中经常使用配置:
package.json
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.15",
"@vue/cli-plugin-eslint": "^5.0.0",
"@vue/cli-plugin-router": "~4.5.15",
"@vue/cli-plugin-vuex": "~4.5.15",
"@vue/cli-service": "~4.5.15",
"babel-eslint": "^10.1.0",
"eslint": "^7.22.0",
"eslint-config-tpconfig": "^0.3.3",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-vue": "^7.7.0"
},
.eslintrc.js
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true,
jquery: true
},
extends: ['plugin:vue/recommended', 'eslint:recommended'],
rules: {
'vue/no-mutating-props': 0, // 先不管对props的修改
'vue/max-attributes-per-line': [
2,
{
singleline: 20,
multiline: {
max: 10,
allowFirstLine: false
}
}
],
'vue/singleline-html-element-content-newline': 'off',
'vue/html-self-closing': [
'error',
{
html: {
void: 'always',
normal: 'never',
component: 'never'
},
svg: 'any',
math: 'any'
}
],
'vue/multiline-html-element-content-newline': 'off',
'vue/name-property-casing': ['error', 'PascalCase'],
'vue/no-v-html': 'off',
'vue/html-indent': ['error', 4, { baseIndent: 1 }],
'vue/script-indent': ['error', 4, { baseIndent: 0 }],
'accessor-pairs': 2,
'arrow-spacing': [
2,
{
before: true,
after: true
}
],
'block-spacing': [2, 'always'],
'brace-style': [
2,
'1tbs',
{
allowSingleLine: true
}
],
camelcase: [
0,
{
properties: 'always'
}
],
'comma-dangle': [2, 'never'],
'comma-spacing': [
2,
{
before: false,
after: true
}
],
'comma-style': [2, 'last'],
'constructor-super': 2,
curly: [2, 'multi-line'],
'dot-location': [2, 'property'],
'eol-last': 2,
eqeqeq: ['error', 'always', { null: 'ignore' }],
'generator-star-spacing': [
2,
{
before: true,
after: true
}
],
'handle-callback-err': [2, '^(err|error)$'],
'jsx-quotes': [2, 'prefer-single'],
'key-spacing': [
2,
{
beforeColon: false,
afterColon: true
}
],
'keyword-spacing': [
2,
{
before: true,
after: true
}
],
'new-cap': [
2,
{
newIsCap: true,
capIsNew: false
}
],
'new-parens': 2,
'no-array-constructor': 2,
'no-caller': 2,
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty-character-class': 2,
'no-empty-pattern': 2,
// 'no-eval': 2,
'no-ex-assign': 2,
'no-extend-native': 2,
'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
'no-extra-parens': [2, 'functions'],
'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
'no-implied-eval': 2,
'no-inner-declarations': [2, 'functions'],
'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
'no-iterator': 2,
'no-label-var': 2,
'no-labels': [
2,
{
allowLoop: false,
allowSwitch: false
}
],
'no-lone-blocks': 2,
'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
'no-multi-str': 2,
'no-multiple-empty-lines': [
2,
{
max: 1
}
],
'no-native-reassign': 2,
'no-negated-in-lhs': 2,
'no-new-object': 2,
'no-new-require': 2,
'no-new-symbol': 2,
'no-new-wrappers': 2,
'no-obj-calls': 2,
'no-octal': 2,
'no-octal-escape': 2,
'no-path-concat': 2,
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
'no-sequences': 2,
'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
'no-sparse-arrays': 2,
'no-this-before-super': 2,
'no-throw-literal': 2,
'no-trailing-spaces': 2,
'no-undef': 2,
'no-undef-init': 2,
'no-unexpected-multiline': 2,
'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [
2,
{
defaultAssignment: false
}
],
'no-unreachable': 2,
'no-unsafe-finally': 2,
'no-unused-vars': [
2,
{
vars: 'all',
args: 'none'
}
],
'no-useless-call': 2,
'no-useless-computed-key': 2,
'no-useless-constructor': 2,
'no-useless-escape': 0,
'no-whitespace-before-property': 2,
'no-with': 2,
'one-var': [
2,
{
initialized: 'never'
}
],
'operator-linebreak': [
2,
'after',
{
overrides: {
'?': 'before',
':': 'before'
}
}
],
'padded-blocks': [2, 'never'],
quotes: [
2,
'single',
{
avoidEscape: true,
allowTemplateLiterals: true
}
],
semi: [2, 'always'],
'semi-spacing': [
2,
{
before: false,
after: true
}
],
'space-before-blocks': [2, 'always'],
'space-before-function-paren': [2, 'never'],
'space-in-parens': [2, 'never'],
'space-infix-ops': 2,
'space-unary-ops': [
2,
{
words: true,
nonwords: false
}
],
'spaced-comment': [
2,
'always',
{
markers: ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
}
],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
yoda: [2, 'never'],
'prefer-const': 2,
'object-curly-spacing': [
2,
'always',
{
objectsInObjects: false
}
],
'array-bracket-spacing': [2, 'never'],
strict: 2, // 使用严格模式
'max-statements': [2, 50, { ignoreTopLevelFunctions: true }],
'no-console': process.env.NODE_ENV === 'production' ? 0 : 0,
'no-debugger': process.env.NODE_ENV === 'production' ? 0 : 0
},
globals: { _: true, Base64: true, axios: true, BMap: true }
};