前端进阶(3) - 怎样提高代码质量

怎样提高代码质量

尽管写了多年的代码,可是始终有一件事不敢肯定,就是本身的代码究竟写得好很差?这个问题很难有确切的答案,由于这个跟风格、规范有很大关系,而风格、规范很难说好仍是很差。javascript

但我以为好的代码,必定是能让别人阅读起来有一种爽心悦目的感受。css

1. 开发规范

不论是团队协做仍是我的独立开发,遵循必定的开发规范都是颇有必要的。就团队协做来讲,可能每一个人的风格迥然不一样,若是没有规范的约束的话,团队之间的协做会大打折扣的。而就我的独立开发来讲,很难说一年后的你回头看今天本身写的代码是满意的。html

js 开发规范

通常前端开发的主要工做都要 js 部分,因此通常前端开发规范都是对 js 而言的。前端

承认度比较高的有:java

css 开发规范

承认度比较高的有:node

2. 使用工具检查、自动矫正与优化

尽管有规范可循,但其实开发的时候并不知道本身的代码是不是符合规范的,因此就须要工具来检查与矫正代码。react

2.1 检查与自动矫正

承认度比较高的有:webpack

  1. eslint:检查 js 语法(包括 jsx 语法),而后最大程度的矫正不符合规范的代码;
  2. stylelint:检查 css 语法(包括 less, scss 语法),而后最大程度的矫正不符合规范的代码。

安装

目录文件git

|-- root/                    // 项目根目录
    |-- package.json
    |-- .eslintrc            // eslint 配置文件
    |-- .eslintignore        // eslint 忽略配置,相似 .gitignore
    |-- .stylelintrc         // stylelint 配置文件
    |-- .stylelintignore     // stylelint 忽略配置,相似 .gitignore

package.jsones6

"scripts": {
  "eslint": "eslint .",                             // 仅检查
  "eslint:fix": "eslint . --fix",                   // 检查以后自动矫正
  
  "stylelint": "stylelint \"./**/*.{css,less,sass,scss}\"",             // 仅检查
  "stylelint:fix": "stylelint \"./**/*.{css,less,sass,scss}\" --fix"    // 检查以后自动矫正
},
"devDependencies": {
  "eslint": "^4.19.1",                              // eslint 主文件
  "babel-eslint": "^8.2.5",                         // babel 转码器 for eslint
  "eslint-config-airbnb": "^17.0.0",                // airbnb eslint 规则
  "eslint-config-prettier": "^2.9.0",               // prettier eslint 规则
  "eslint-plugin-babel": "^5.1.0",                  // eslint 的 babel 转码插件
  "eslint-plugin-import": "^2.13.0",                // eslint 检查模块输入输出是否正确的插件
  "eslint-plugin-jsx-a11y": "^6.1.0",               // eslint jsx 语法检查的一个插件
  "eslint-plugin-prettier": "^2.6.2",               // prettier eslint 插件
  "eslint-plugin-react": "^7.10.0",                 // eslint react 语法检查插件
  
  "stylelint": "^9.3.0",                            // stylelint 主文件
  "stylelint-config-prettier": "^3.3.0",            // prettier stylelint 规则
  "stylelint-config-standard": "^18.2.0"            // standard stylelint 规则
},

.eslintrc

{
  "parser": "babel-eslint",
  "extends": ["airbnb", "prettier"],
  "env": {
    "browser": true,
    "node": true,
    "es6": true,
    "mocha": true,
    "jest": true,
    "jasmine": true
  },
  "rules": {
    ... // 更多本身定义的规则
  }
}

.stylelintrc

{
  "extends": ["stylelint-config-standard", "stylelint-config-prettier"],
  "rules": {
    ... // 更多本身定义的规则
  }
}

运行命令

npm run eslint           // 检查项目中的 js(jsx) 语法
npm run eslint:fix       // 检查项目中的 js(jsx) 语法,并最大程度的矫正

npm run stylelint        // 检查项目中的 css(less,scss) 语法
npm run stylelint:fix    // 检查项目中的 css(less,scss) 语法,并最大程度的矫正

2.2 代码优化

eslintstylelint 在对代码作检查和自动矫正时,只保证代码的语法是符合必定的规范,并不对代码的格式作任何优化,因此,自动矫正后的代码可能格式会不太好,阅读性不过高。

因此,通常会在对代码检查与自动矫正以后作代码格式优化。

使用比较多的:prettier.

安装

目录文件

|-- root/                    // 项目根目录
    |-- package.json
    |-- .prettierrc          // prettier 配置文件
    |-- .prettierignore      // prettier 忽略配置,相似 .gitignore

package.json

"scripts": {
  // 对 js,jsx,css,less,md,json 文件进行优化
  "prettier": "prettier --write \"./**/*.{js,jsx,css,less,md,json}\""
},
"devDependencies": {
  "prettier": "^1.13.7"
},

.prettierrc

{
  "singleQuote": true,
  "trailingComma": "es5",
  "printWidth": 120,
  "overrides": [
    {
      "files": ".prettierrc",
      "options": { "parser": "json" }
    }
  ]
}

运行命令

npm run prettier

2.3 强制对代码进行检查、自动矫正与优化

尽管定好了规范与工具命令,但开发人员彻底能够跳过这些步骤,这尤为是在团队开发中很难强制其余组员会去作代码检查、自动矫正与优化。

因此,使用工具强制开发人员对代码进行检查、自动矫正与优化,就显得颇有必要了。

使用比较多的:

  • husky:对 git 进行 hook,能够在 git 操做以前作一些操做;
  • lint-staged:对当前 git 提交的代码进行一些操做。

package.json

"scripts": {
  "precommit": "npm run lint-staged",     // 在 git 提交以前运行 lint-staged 命令
  "lint-staged": "lint-staged",           // 对 git 将要提交的代码作操做
},
"devDependencies": {
  "husky": "^0.14.3",
  "lint-staged": "^7.2.0",
},
"lint-staged": {
  "**/*.{js,jsx}": [
    "eslint --fix",                      // 对 js,jsx 文件进行 eslint 检查、自动矫正 
    "prettier --write",                  // 而后 使用 prettier 进行代码格式优化
    "git add"                            // 最后从新添加
  ],
  "**/*.{css,less}": [
    "stylelint --fix",                   // 对 css,less 文件进行 stylelint 检查、自动矫正
    "prettier --write",                  // 而后 使用 prettier 进行代码格式优化
    "git add"                            // 最后从新添加
  ],
  "**/*.{md,json}": [
    "prettier --write",                  // 使用 prettier 进行代码格式优化
    "git add"                            // 最后从新添加
  ]
},

这样,在每次 git commit 以前,都会对将要提交的文件进行检查、自动矫正与优化,若是其中有一项发生错误,本次提交都会失败。而后开发人员调整代码以后再进行提交,只有每项任务都是没问题的,才能提交成功。

这样,即可使每一个开发人员都是按照必定的规范与风格写代码的。

3. 编辑器配置:.editorconfig

有了规范,也加上了工具作自动化代码检查、矫正与优化,但还有一点须要说起一下,就是在团队协做中,每一个开发人员可能使用的编辑器不同,编辑器的配置也不同,这就致使工具在作格式优化的时候,不一样的开发人员中输出的代码不同。

这就须要配置文件 .editorconfig 去统一每一个开发人员的编辑器配置。

目录文件

|-- root/                    // 项目根目录
    |-- .editorconfig        // 编辑器配置文件

.editorconfig

# http://editorconfig.org
root = true

[*]
indent_style = space                    # 输入的 tab 都用空格代替
indent_size = 2                         # 一个 tab 用 2 个空格代替
end_of_line = lf                        # 换行符使用 unix 的换行符 \n
charset = utf-8                         # 字符编码 utf-8
trim_trailing_whitespace = true         # 去掉每行末尾的空格
insert_final_newline = true             # 每一个文件末尾都加一个空行

[*.md]
trim_trailing_whitespace = false        # .md 文件不去掉每行末尾的空格

更多的编辑器配置规则,能够查看 http://editorconfig.org.

4. 业务逻辑优化

上面提到的这些只是风格、规范、语法上的优化,但对编码质量的评估更多的是在业务逻辑具体实现这一块。

通常来讲,业务逻辑实现的优化离不开下面几个方向:

  1. 模块化:

    • js 的模块化已经很成熟了,目前使用最多的是 commonjs 模块化规范和 es6 模块;
    • css 的模块化也一直在探索中,以前也专门写了一篇 CSS 模块化,能够参考下;
    • html 没有模块化,可是能够将一个很长的 html 文件进行分块,参考 html-loader
  2. 组件化:当项目变大、变多,不少公共的代码须要复用或者跨项目使用的时候,组件化就变得很必要了,以前也专门写了一篇 组件化,能够参考下;
  3. 逻辑解耦:把一个复杂的逻辑,分割成多个子逻辑,而后将子逻辑串起来,或者把多个交叉逻辑的公共部分拆出来,而后再挨个串起来;
  4. 功能分块:细化一个一个的功能为单独的模块。

5. 逻辑解耦

逻辑解耦就是把一个复杂的逻辑,分割成多个子逻辑,或者把多个交叉逻辑的公共部分拆成单个逻辑。这样作的目的是下降应用的复杂度,更据阅读性。

好比,3 个串行的 ajax 请求,能够分割成多个子逻辑:

$.getJSON(url1, data1, res1 => {
  // do something with res1
  
  $.getJSON(url2, data2, res2 => {
    // do something with res2
    
    $.getJSON(url3, data3, res3 => {
      // do something with res3
    });
  });
});

逻辑解耦以后:

const request1 = () => {
  $.getJSON(url1, data1, res1 => {
    // do something with res1
    
    request2();
  }
};
const request2 = () => {
  $.getJSON(url2, data2, res2 => {
    // do something with res2
    
    request3();
  }
};
const request3 = () => {
  $.getJSON(url3, data3, res3 => {
    // do something with res3
  }
};

request1();

再好比,在不一样文件中须要依赖同一个 ajax 请求,能够把交叉逻辑的部分拆成单个逻辑:

# file1.js

$.getJSON(url, data, res => {
  // do something with res
}

# file2.js

$.getJSON(url, data, res => {
  // do something with res
}

逻辑解耦以后:

# request.js

module.exports = cb => {
  $.getJSON(url, data, res => {
    cb(res);
  }
};

# file1.js

const request = require('./request');
request(res => {
  // do something with res
});

# file2.js

const request = require('./request');
request(res => {
  // do something with res
});

6. 功能分块

细化功能为单独的模块也是提高代码质量的一个方式。

好比,将一个文件拆成多个文件(颗粒化):

# util.js

module.exports = {
  func1: args => { ... },
  func2: args => { ... },
  func3: args => { ... },
};

将功能分块以后:

# util/func1.js

module.exports = args => { ... };

# util/func2.js

module.exports = args => { ... };

# util/func3.js

module.exports = args => { ... };

再好比,将一个大功能块分割成多个小功能块:

$.getJSON(url, data, res => {
  // 渲染页面
  ...
  
  // 初始化组件
  ...
  
  // 装载数据
  ...
  
  // 绑定模型
  ...
  
  // ...
  ...
}

通常这种状况下,一个功能代码块就可能会很长,200 行都有可能,这个时候就须要将其分割成多个小代码块:

const renderPages = res => { ... };
const initComponents = res => { ... };
const fillData = res => { ... };
const bindModels = res => { ... };
...

$.getJSON(url, data, res => {
  // 渲染页面
  renderPages();
  
  // 初始化组件
  initComponents();
  
  // 装载数据
  fillData()
  
  // 绑定模型
  bindModels();
  
  // ...
  ...
}

7. 多阅读

最后,也是最重要的,就是多阅读别人优秀的代码,阅读永远是获取知识最重要的途径,没有之一。

8. 后续

更多博客,查看 https://github.com/senntyou/blogs

做者:深予之 (@senntyou)

版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证