typescript-eslint上手

正所谓,合久必分分久必合。大胆预测一波,从js衍生出出来的ts,要取代js成为每个前端开发的必备武器。

这已经五月了,我就把这碗这热乎的端出来,给大家尝尝。如有错误,欢迎指正。

成品

.eslintrc.js

module.exports = {
  'root': true,
  'env': {
    'browser': true,
    'es6': true,
    // "react-native/react-native": true,
  },
  "settings": {
    "react": {
      "createClass": "createReactClass",
      "pragma": "React",
      "version": "detect",
      "flowVersion": "0.53",
    }
  },
  'extends': [
    'plugin:react/recommended',
    "plugin:react-native/all",
    "plugin:jsx-a11y/recommended",
    'plugin:@typescript-eslint/recommended',
    'prettier',
    'prettier/@typescript-eslint',
  ],
  'parser': '@typescript-eslint/parser',
  'globals': {
    'Atomics': 'readonly',
    'SharedArrayBuffer': 'readonly',
  },
  'parserOptions': {
    'ecmaFeatures': {
      'jsx': true,
    },
    'ecmaVersion': 2018,
    'sourceType': 'module',
    // 'project': './tsconfig.json',
  },
  'plugins': [
    '@typescript-eslint',
    'react',
    "react-native",
    "jsx-a11y",
  ],
  'rules': {
    '@typescript-eslint/explicit-member-accessibility': ['error', { accessibility: 'no-public' }],
    '@typescript-eslint/explicit-function-return-type': [
      // 'warn',
      'off',
      {
        allowExpressions: true,
        allowTypedFunctionExpressions: true,
      }
    ],
    '@typescript-eslint/no-explicit-any': 'off',
    '@typescript-eslint/no-use-before-define': 'off',
    '@typescript-eslint/camelcase': ['off', {properties: 'always'}],
    '@typescript-eslint/no-unused-vars': ['error', {
      'vars': 'all',
      'args': 'none',
      'ignoreRestSiblings': true,
    }],
    "react-native/no-color-literals": 0,
    "react-native/sort-styles": 0,
    "react-native/no-inline-styles":0,
  },
};

package.json

{
  "name": "rn-demo",
  "version": "1.0.0",
  "private": true,
  "description": "react-native trade module",
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest",
    "lint_fix": "eslint 'src/**/*.{ts,js,tsx,jsx}' --fix -o eslint_log.log",
  },
  "dependencies": {
    "@types/es6-shim": "^0.31.37",
    "@types/node": "^10.3.1",
    "@types/prop-types": "^15.5.3",
    "@types/react": "^16.3.16",
    "@types/react-native": "^0.55.17",
    "@ymm/rn-lib": "0.0.66",
    "global": "^4.3.2",
    "mobx": "3.4.1",
    "mobx-react": "4.3.5",
    "prop-types": "^15.6.2",
    "react": "16.0.0",
    "react-native": "0.51.0",
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^1.7.0",
    "babel-eslint": "^8.2.6",
    "babel-jest": "23.0.0-alpha.0",
    "babel-plugin-mobx-deep-action": "^1.6.0",
    "babel-plugin-transform-decorators-legacy": "^1.3.5",
    "babel-plugin-transform-regenerator": "^6.26.0",
    "babel-preset-react-native": "4.0.0",
    "babel-preset-react-native-stage-0": "1.0.1",
    "babel-preset-stage-0": "6.24.1",
    "babel-preset-stage-2": "6.24.1",
    "cross-env": "3.1.3",
    "diff-match-patch": "^1.0.0",
    "eslint": "^5.16.0",
    "eslint-config-google": "^0.13.0",
    "eslint-config-prettier": "^4.2.0",
    "eslint-config-react": "^1.1.7",
    "eslint-config-standard": "^12.0.0",
    "eslint-plugin-import": "^2.17.2",
    "eslint-plugin-jsx-a11y": "^6.2.1",
    "eslint-plugin-node": "^9.0.1",
    "eslint-plugin-promise": "^4.1.1",
    "eslint-plugin-react": "^7.13.0",
    "eslint-plugin-react-native": "^3.7.0",
    "eslint-plugin-standard": "^4.0.0",
    "http": "^0.0.0",
    "jest": "23.0.0-alpha.0",
    "path": "^0.12.7",
    "react-native-cli": "^2.0.1",
    "react-native-typescript-transformer": "^1.2.10",
    "react-test-renderer": "16.0.0",
    "readline-sync": "^1.4.9",
    "source-map": "^0.7.3",
    "typescript": "^3.4.5",
    "zip-local": "^0.3.4"
  },
  "jest": {
    "preset": "react-native"
  },
}


运行

npm i
npm run lint_fix // 错误文件或输出到log文件

准备

  • 一个基于Typescript实现的RN工程

安装

  • 安装eslint
  • 安装eslint-config-xx
  • 配置.eslintrc.xx文件
  • 运行eslint命令

安装eslint

也可移步官方教程

推荐安装eslint到本地,而不是全局
$ npm install eslint --save-dev

初始化配置文件(推荐尝试下这个命令,而不是直接拿别人写好的.eslintrc.xx文件)
$ ./node_modules/.bin/eslint --init

最后,就可以运行想检查的命令了:eslint [options] file.js [file.js] [dir]
$ ./node_modules/.bin/eslint yourfile.js

安装eslint-config-xx、eslint-plugin-xx

eslint自带的规则不能满足我们的需求,就需要更多的插件来补偿。

推荐插件

// 通用
npm install --save-dev eslint-config-prettier
npm install --save-dev @typescript-eslint/eslint-plugin
// React & RN 支持
npm install --save-dev eslint-config-react
npm install --save-dev eslint-config-react-native
npm install --save-dev eslint-plugin-jsx-a11y

配置.eslintrc.xx文件

 'extends': [
    'plugin:react/recommended',
    "plugin:react-native/all",
    "plugin:jsx-a11y/recommended",
    'plugin:@typescript-eslint/recommended',
    'prettier',
    'prettier/@typescript-eslint',
  ],
  'parser': '@typescript-eslint/parser',
  'plugins': [
    '@typescript-eslint',
    'react',
    "react-native",
    "jsx-a11y",
  ]

运行eslint命令

./node_modules/.bin/eslint 'src/**/*.{ts,js,tsx,jsx}' --fix -o eslint_log.log

为了方便,放到packgae.json里面

"scripts": {
    "lint_fix": "eslint 'src/**/*.{ts,js,tsx,jsx}' --fix -o eslint_log.log",
  },

效果如下

/Users/yundada/Desktop/ymm-code/repos_rn/ymm-rn-module-demo/src/components/ActionBackgroundView/index.tsx
  11:9  error  'Text' is defined but never used  @typescript-eslint/no-unused-vars

/Users/yundada/Desktop/ymm-code/repos_rn/ymm-rn-module-demo/src/components/BadgeView/index.tsx
  3:8  error  'styles' is defined but never used  @typescript-eslint/no-unused-vars

/Users/yundada/Desktop/ymm-code/repos_rn/ymm-rn-module-demo/src/components/BaseComponet/index.tsx
  4:21  error  'any' is defined but never used   @typescript-eslint/no-unused-vars
  6:22  error  'DLog' is defined but never used  @typescript-eslint/no-unused-vars

✖ 270 problems (270 errors, 0 warnings)


若是自己尝试,可能会遇到的几个问题

No files matching the pattern "src" were found.

➜  ymm-rn-module-demo git:(master) ./node_modules/.bin/eslint src

Oops! Something went wrong! :(

ESLint: 5.16.0.
No files matching the pattern "src" were found.
Please check for typing mistakes in the pattern.

这个stackoverflow没有找到答案

解决方法: ./node_modules/.bin/eslint src/**/.

➜  ymm-rn-module-demo git:(ef88f03) ./node_modules/.bin/eslint src/**/*.*

/Users/yundada/Desktop/ymm-code/repos_rn/ymm-rn-module-demo/src/components/ActionBackgroundView/index.tsx
  11:9  error  'YMMText' is defined but never used  @typescript-eslint/no-unused-vars

【2】No files matching the pattern "src" were found.

基于上个问题,src/**/*.*只能匹配src下面一个目录,src/a/b/a.ts就匹配不到了 解决方法:匹配字符串加上单引号即可

➜  ymm-rn-module-demo git:(ef88f03) ./node_modules/.bin/eslint 'src/**/*.*'

@typescript-eslint不生效、引入新eslint-plugin-xx,之前的不生效了

比如下面的配置,我发现@typescript-eslint不生效了

'extends': [
    'plugin:@typescript-eslint/recommended',
    'prettier',
    'prettier/@typescript-eslint',
    'plugin:react/recommended',
    "plugin:react-native/all",
    "plugin:jsx-a11y/recommended",
  ],

这里是新引入的插件把推荐的规则覆盖了,调整下顺序即可。

'extends': [
    'plugin:react/recommended',
    "plugin:react-native/all",
    "plugin:jsx-a11y/recommended",
    'plugin:@typescript-eslint/recommended',
    'prettier',
    'prettier/@typescript-eslint',
  ],

资料

05-16 23:00