Skip to content

react native工程化:规范化 #9

@lixingdecai

Description

@lixingdecai

RN 工程规范化: eslint + prettier + vscode

编码规范:每个人的编码风格和习惯不同,例如有些人习惯句尾写封号,但是如果这些代码风格不进行一个
统一的规范,在多人的项目的代码管理中,就会造成很多不必要的代价。目前市场主流的编码规范Airbnb的编码风格,我们也是基于这套 -->
Airbnb React/JSX 编码规范

规范化的好处

  • 提高阅读性: 统一编码风格,编码和注释都像是来自同一个人。干净 整洁 看起来就很爽。
  • 减少出错率:不符合代码规则的代码,很多就是错误的。一定层度可以规避很多风险
  • 提高开发效率:代码风格不统一,在团队代码合并等很容易引起冲突
  • 提高个人能力:有很多你默认习惯的方法,其实是错误的。代码检测修复,也是一个非常好的自检和学习的过程。
  • 方便代码工程管理:诸多好处很显然可以让你在对工程 和 代码的管理上少了很多麻烦

规范性的好处很多,但是他的优先级并不是最高,它是在你项目发展到一定层度,项目相对稳定可以引进的。它是可以让你项目开发管理上变得更好的东西,但并不是必须配。

编辑器选择微软的VS code
vscode 使用 代码统一风格工具.editorconfig

使用vscode + eslint + prettier 修改后的效果图:
image

左侧41个文件是eslint fix 自动修复的文件数;中间是前后两个文件的代码差异比对,红色区域是eslint 自动修复的语法规则。右侧带有下滑线是不符合设定的eslint语法规则,需要手动修改的代码

使用Eslint 代码格式检测工具

  1. VSCode 安装 eslint 插件
    image

  2. npm install --save-dev eslint

  3. npm install --save-dev babel-eslint eslint-plugin-react-native eslint-plugin-jsx-a11y eslint-plugin-import
    (或者将下面的package.json拷到你的项目直接安装)
    babel-eslint 是 eslint 的解析器
    eslint-plugin-jsx-a11y 是 jsx 的插件
    eslint-plugin-react-native 是 react native 插件
    eslint-plugin-import 是支持es6 import/export 的插件
    eslint-config-airbnb 基于airbnb的eslint代码规则

附一份package.json的依赖配置作参考

 "dependencies": {
    "antd-mobile": "^2.0.0-beta.2",
    "babel-plugin-import": "^1.5.0",
    "create-react-class": "^15.6.2",
    "prop-types": "^15.6.0",
    "react": "16.0.0-alpha.12",
    "react-native": "^0.48.3",
    "react-native-animatable": "^1.1.1",
    "react-native-blur": "^3.1.2",
    "react-native-elements": "^0.11.2",
    "react-native-picker": "^4.0.18",
    "react-native-picker-android": "^1.0.3",
    "react-native-storage": "^0.2.1",
    "react-native-vector-icons": "^4.0.1",
    "react-navigation": "^1.0.0-beta.11"
  },
  "devDependencies": {
    "babel-eslint": "^8.0.1",
    "babel-jest": "19.0.0",
    "babel-preset-react": "^6.24.1",
    "babel-preset-react-native": "1.9.1",
    "eslint": "^4.9.0",
    "eslint-config-airbnb": "^16.1.0",
    "eslint-plugin-import": "^2.8.0",
    "eslint-plugin-jsx-a11y": "^6.0.2",
    "eslint-plugin-react": "^7.4.0",
    "eslint-plugin-react-native": "^3.1.0",
    "jest": "19.0.2",
    "q": "^1.5.0",
    "react-native-webpack-server": "^0.9.3",
    "react-test-renderer": "~15.4.0",
    "shelljs": "^0.7.7"
  },
  1. eslint --init
    image
    上图是我的style,怕麻烦可以直接选择Airbnb的配置
    image

当然相对于Airbnb,我们RN工程的一些差异性,我们还是做了小的改动,下面是我的.eslintrc 中eslint的一些规则:

module.exports = {
    "extends": ["airbnb"],
    "parser": "babel-eslint",
    "plugins": [
        "react",
        "react-native",
        "jsx-a11y",
        "import"
    ],
    rules: {
        // 0 = off, 1 = warn, 2 = error
        // FB配置参考:
        // https://github.com/facebook/react-native/blob/8baaad9b0fbda2b02bb1834452aa63cac7910dc5/.eslintrc
        "arrow-parens": ["error", "as-needed"],
        "global-require": 0,
        "no-use-before-define": 0,       // disallow use of variables before they are defined
        "max-len": 0,                    // specify the maximum length of a line in your program (off by default)
        "no-console": 0,                 // disallow use of console (off by default in the node environment)
        "no-undef": 2,                   // disallow use of undeclared variables unless mentioned in a /*global */ block
        "no-unused-expressions": ["error", { "allowShortCircuit": true, "allowTernary": true }], // allow short circuit allow  ternary
        // "no-empty": [2, { methods: true }],
        "no-unused-vars": 0,
        "no-underscore-dangle": 0,
        "no-param-reassign": ["error", { "props": false }],
        "radix": 0,
        "block-scoped-var": 0,           // treat var statements as if they were block scoped (off by default)
        "complexity": 0,                 // specify the maximum cyclomatic complexity allowed in a program (off by default)
        "consistent-return": 0,          // require return statements to either always or never specify values
        "class-methods-use-this": 0,
        // allow async-await
        'generator-star-spacing': 0,
        'curly': 0,
        "object-curly-spacing": 0,
        "one-var": 0,
        "no-return-assign": 1,           // disallow use of assignment in return statement
    
        "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
        "react/self-closing-comp": 1,
        "react/jsx-closing-bracket-location": 0,
        "react/prop-types": 0, // 避免redux等注入属性的情况
        "react/forbid-prop-types": 0
      },
    
      // 这里设置可能用到的全局变量
      "globals": {
        "window": true,
        "__DEV__": true,
        "__APP__": true,
        "__ANDROID__": true,
        "__IOS__": true
      }
};
  1. 执行eslint --ext .js ./src --fix
    但是执行完eslint --ext .js ./src --fix,几个简单页面的demo 报了上百个错误,就这些报错,估计语法错误,估计得改好久时间。
    而平常使用的格式化或者代码美化工具,没办法按照eslint的规则进行美化。我使用的react-beautify插件,就不行。在你改好代码,比如表达式最后一句,结尾使用逗号,格式化会将其删除
    image

使用Prettier 代码格式化工具

https://www.npmjs.com/package/prettierrc

  1. 安装prettier

1.1. npm install prettier --save-d / yarn add prettier --dev

1.2. 安装插件

prettier 在每个对应的IDE都有对应的插件,我使用的是VS code。就以vs code举例。搜索prettier插件的第一条就是,如下图所示
image

  1. 配置规则
    vscode 配置规则地址
    2.1. 直接在 package.json 里面配置
{
  "name": "projectname",
  "version": "1.0.0",
  "description": "test",
  "dependencies": {
    "prettier": "latest"
  },
  "prettier": {
    "singleQuote": true, // 规则 
     ……
  }
}

2.2. 配置文件.prettier
配置内容如下

{
    "useTabs": false,      // Indent lines with tabs instead of spaces. 
    "printWidth": 80,      // Specify the length of line that the printer will wrap on. 
    "tabWidth": 2,         // Specify the number of spaces per indentation-level. 
    "singleQuote": false,  // Use single quotes instead of double quotes. 
    /**
     * Print trailing commas wherever possible.
     * Valid options:
     *   - "none" - no trailing commas
     *   - "es5" - trailing commas where valid in ES5 (objects, arrays, etc)
     *   - "all" - trailing commas wherever possible (function arguments)
     */
    "trailingComma": "none",
    /**
     * Do not print spaces between brackets.
     * If true, puts the > of a multi-line jsx element at the end of the last line instead of being
     * alone on the next line
     */
    "jsxBracketSameLine": false,
    /**
     * Specify which parse to use.
     * Valid options:
     *   - "flow"
     *   - "babylon"
     */
    "parser": "babylon",
    /**
     * Do not print semicolons, except at the beginning of lines which may need them.
     * Valid options:
     * - true - add a semicolon at the end of every line
     * - false - only add semicolons at the beginning of lines that may introduce ASI failures
     */
    "noSemi": true,
    /**
     * Add additional logging from prettierrc (not prettier itself).
     * Defaults to false
     * Valid options:
     * - true - enable additional logging
     * - false - disable additional logging
     */
    "rcVerbose": true
}

坑: 使用此配置文件的时候,请将里面的注释删除,不然可能不生效

prettier 和 Eslint 冲突

其实prettier 的格式化不完全和 eslint的规则相符,还是会有冲突的地方。从上面的配置文件可以看出,prettier 可配置的选项还是比较简单的。在有些地方prettier 还是会把一些正确的格式成eslint不允许的。这种时候只能去修改eslint的配置文件.eslintrc

  1. arrow-parens 箭头函数的参数是否需要括号包裹

出现:
image

prettier格式化后:
image

解决:
在.eslintrc中添加 "arrow-parens": ["error", "as-needed"]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions