## 如何实现代码格式化
代码格式统一规范,代码规范是前半部分,如何保证规范是后半部分,如何去落实这后半部分,这值得我们去思考。
我们想着通过手动去修改自己的代码格式,但这是不是很麻烦,可能眼花一下就少改了一部分,可能要改的地方太多了,太耗时间太累了(即使自己写的时候是按照规范来的,可能还是有很多不符合规范的东西)。
所以,我们不可能选择手动的方式去统一我们的代码,因为这是很蠢的一种行为。
那么,有什么办法可以实现这些东西呢?
1.**普通的代码(没有构建类似vue、react项目那样的npm包管理环境),如何实现代码的格式化**(以下,将借助vscode进行代码自动格式化)
* 环境:安装node(个人的版本是v10.16.3)
* 工具:vscode(个人的版本是v1.39)
* 下载几个npm包(全局安装):eslint@5.16.0(这里使用的不是最新的版本,至于为什么不使用最新版本,这个我们之后再来说这个问题)
* 下载vscode插件:ESLint、Beautify、Prettier - Code formatter
* 在项目根目录创建eslint的配置文件(.eslintrc.js):
```
.eslintrc.js:
var rules = require('./eslint_rules')
module.exports = {
"root": true,
"parserOptions": {},
"env": {
"browser": true, // 预定义的全局变量,这里是浏览器环境
"node": true, // 预定义的全局变量,这里是node环境
"es6": true // 预定义的全局变量,这里是ES6环境
},
"rules": rules
}
```
rules是eslint的规则,由于规则比较多,所以将rules单独存放到一个外部文件,如下:
```
eslint_rules.js:
module.exports = {
'no-console': process.env.NODE_ENV === 'production' ?
1 : 0,
'no-debugger': process.env.NODE_ENV ===
'production' ? 2 : 0,
'no-func-assign': 2,
'no-sparse-arrays': 2,
'no-unreachable': 2,
'curly': ['error', 'all'],
'default-case': 2,
'no-multi-spaces': 2,
'no-new-wrappers': 2,
'no-redeclare': 2,
// "no-undefined": 2,
'no-undef-init': 2,
// "no-undef": 2,
'no-unused-vars': 1,
'block-spacing': 2,
'brace-style': ['error', '1tbs'],
'comma-spacing': 2,
'comma-style': 2,
'computed-property-spacing': 2,
'func-call-spacing': 2,
'indent': ['error', 2],
'keyword-spacing': 2,
'max-statements-per-line': ['error', {max: 1}],
'no-mixed-spaces-and-tabs': 2,
'no-multiple-empty-lines': 2,
'no-tabs': 0,
'no-whitespace-before-property': 2,
'object-curly-newline': ['error', {multiline: true}],
'one-var': ['error', {
initialized: 'never',
uninitialized: 'always',
}],
'quotes': ['error', 'single', {'allowTemplateLiterals': true}],
'semi': ['error', 'never'],
'space-before-blocks': ['error', {
'functions': 'always',
'keywords': 'always',
'classes': 'always'
}],
'space-before-function-paren': ['error', 'always'],
'space-unary-ops': ['error', {
words: true,
nonwords: false
}],
'space-infix-ops': 2,
'arrow-spacing': 2,
'generator-star-spacing': ['error', 'after'],
'no-const-assign': 2,
'no-duplicate-imports': 2,
'no-compare-neg-zero': 2,
'no-eval': 2,
'no-invalid-regexp': 2,
'no-dupe-args': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty': 2,
'no-empty-character-class': 2,
'no-extra-semi': 2,
'no-regex-spaces': 2,
'no-unexpected-multiline': 2,
'valid-typeof': 2,
'no-lone-blocks': 2,
'no-loop-func': 2,
'no-self-assign': 2,
'no-self-compare': 2,
'no-unused-expressions': 2,
'no-useless-concat': 2,
'no-with': 2,
// "no-use-before-define": 2,
'no-dupe-class-members': 2,
'no-unneeded-ternary': 2
}
```
* 打开vscode的自定义配置文件:mac(code -> preferences(首选项)-> Settings(设置)-> 搜索settings.json -> 点击 "edit in settings.json" ),如果是windows,首选项在file菜单里面,后续的操作一样
![](https://img.kancloud.cn/62/59/6259b0fdfd9d59dc54f1368f311ee2fc_2980x1674.jpg)
* 配置settings.json,如下:
```
{
"editor.fontSize": 14,
// vscode默认启用了根据文件类型自动设置tabsize的选项
"editor.detectIndentation": false,
// 重新设定tabsize
"editor.tabSize": 2,
// 每次保存的时候自动格式化
"editor.formatOnSave": true,
// 设置默认的js格式化工具
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
// 设置默认的scss格式化工具
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
// 设置默认的html格式化工具
"[html]": {
"editor.defaultFormatter": "HookyQR.beautify"
},
// 每次保存的时候将代码按eslint格式进行修复
"eslint.autoFixOnSave": true,
// 添加 vue 支持
"eslint.validate": [
"javascript",
"javascriptreact",
{
"language": "vue",
"autoFix": true
}
],
"eslint.options": {
"configFile": "./.eslintrc.js"
}
}
```
* 保存配置文件之后我们便可以在保存代码时对代码进行格式化(注意:对于eslint规则进行修改之后必须重新打开vscode,不然修改后的规则不会生效):
![](https://img.kancloud.cn/5f/d1/5fd1e37b4df744fbc50f56e4881f04e3_1854x888.gif)
上面所录的gif图中,每次保存文件的时候都会对html、css或js进行相应的代码格式化。
2. **构建了npm环境的项目(比如说vue项目、react项目等)如何进行项目代码的格式化呢 **
相同的,也可以基于方法一实现,接下来以vue项目为例:
* npm包除了已经安装好的eslint,还需要安装babel-eslint、eslint-plugin-vue和eslint-plugin-import
* vscode插件保持不变,对eslint配置文件新增几项配置,如下:
```
var rules = require('./eslint_rules')
module.exports = {
"root": true,
"parserOptions": {
"parser": "babel-eslint", // 解析器,这里我们使用babel-eslint
"ecmaVersion": 6,
"sourceType": "module", // 类型为module,因为代码使用了ECMAScript模块
"ecmaFeatures": {
"jsx": true,
"modules": true
}
},
"env": {
"browser": true, // 预定义的全局变量,这里是浏览器环境
"node": true, // 预定义的全局变量,这里是node环境
"es6": true // 预定义的全局变量,这里是ES6环境
},
"plugins": [
"import",
"vue"
],
"extends": [ 'plugin:vue/base' ],
"rules": rules
}
```
也就是这几项,如图:
![](https://img.kancloud.cn/e6/40/e6405a358d46638489a2db2834191ab2_694x734.png)
* 同样对vscode的自定义配置文件新增几项配置,如下:
```
{
"editor.fontSize": 14,
// vscode默认启用了根据文件类型自动设置tabsize的选项
"editor.detectIndentation": false,
// 重新设定tabsize
"editor.tabSize": 2,
// 每次保存的时候自动格式化
"editor.formatOnSave": true,
// 设置默认的js格式化工具
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
// 设置默认的scss格式化工具
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
// 设置默认的html格式化工具
"[html]": {
"editor.defaultFormatter": "HookyQR.beautify"
},
// 每次保存的时候将代码按eslint格式进行修复
"eslint.autoFixOnSave": true,
// 添加 vue 支持
"eslint.validate": [
"javascript",
"javascriptreact",
{
"language": "vue",
"autoFix": true
}
],
"eslint.options": {
"configFile": "./.eslintrc.js"
},
// 开启vetur格式化程序
"vetur.format.enable": true,
"vetur.validation.template": true,
// 这个按用户自身习惯选择
"vetur.format.defaultFormatter.html": "js-beautify-html",
// 默认的css格式化工具
"vetur.format.defaultFormatter.css": "prettier",
// 让vue中的js按prettier进行格式化
"vetur.format.defaultFormatter.js": "none",
"editor.quickSuggestions": {
"strings": true
}
}
```
也就是这几项,如图:
![](https://img.kancloud.cn/6d/d0/6dd05c9b7dfa11a7c5d1aa8ef440a5fd_773x356.png)
* 配置好后,每次保存文件都会进行格式化代码,vue项目中除了.vue文件,其他都是和法一中是一样的,而我们新增的配置也就是为了服务于.vue文件。
3. **项目完成时,常常需要对项目剩余的格式问题整理找出,然后再处理,那如何做会更高效呢?**
对于构建了npm包环境的项目,一般来说都是代码量比较大的项目,当我们每天下班准备提交代码时,多多少少还会有些代码格式问题需要我们去改,如果对于每个格式问题都是一个一个手动去找然后了解它的问题,最后再把格式改好,这样的话会非常麻烦。
所以,为了摆脱纯手工带来的低效,可以在package.json配置文件中配置eslint代码检测和修复命令,如下:
![](https://img.kancloud.cn/d1/1a/d11a277e3a99b990965663cc5a3c0a84_645x341.png)
当然前提是需要在本地安装eslint包,这样,每次提交代码之前,先通过cnpm run lint对代码进行检测与自动修复,剩余的格式问题会被打印在控制台,如下:
![](https://img.kancloud.cn/ff/ba/ffbadf4345e6cad658040d5686af2aa4_1920x1019.png)
通过点击链接可以直接定位到问题处,然后直接修改即可,是不是方便很多呢。
另外,当然,任何项目都可以构建npm环境(平常写的小demo、静态页面也行,直接通过npm init -y即可),然后采用这种方法,当然这种方法只检测js代码,所以需要配合方法2一起使用。(注:项目代码量不多可以仅使用方法一,毕竟一下显得项目比较冗余,找起来也不麻烦)
4. **如果项目最后还有些代码格式问题没有修复就提交了呢,针对这种情况有办法避免吗?**
既然在这里提了,那肯定是有方法,以一个demo为例:通过 "npm init -y" 构建npm环境 -> 下载eslint到开发依赖中 -> 新建一个test.js文件 -> 将之前用到的eslint配置拷到项目根目录下 -> git初始化仓库(repository)。到此,项目环境已经搭建好了,如图:
![](https://img.kancloud.cn/71/ae/71ae2e6d5efb9540ec9f68e63529074e_1920x1019.png)
接下来,我们先在test.js输入let a = 1与console.log(a),然后git add -A。
接着,在package.json中配置如下:
```
{
"name": "demo",
"version": "1.0.0",
"description": "",
"scripts": {
"lint": "eslint --fix test.js"
},
"pre-commit": "lint",
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"eslint": "^5.16.0",
"pre-commit": "^1.2.2"
}
}
```
注:这里需要下载一个第三方npm包(pre-commit)。
这时,我们git add -A,然后git commit -m "update",他会先执行lint命令,只有eslint没有检测出错误,commit才能提交成功。
![](https://img.kancloud.cn/65/62/65624a277751037bd7a7f2d1551dee7d_1920x1019.png)
![](https://img.kancloud.cn/2a/09/2a098c9dc23f9cc4c7cb402868085c5e_671x164.png)
![](https://img.kancloud.cn/a7/3b/a73b7f3915789fe22da2d1073dbc2454_907x517.png)
当然,除了用pre-commit这个包之外,还有另一种包也能实现(husky),我们也来试试:
* 安装husky:npm install --save-dev husky
* 然后package.json配置如下:
```
{
"name": "demo",
"version": "1.0.0",
"description": "",
"scripts": {
"lint": "eslint --fix test.js"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint "
}
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"eslint": "^5.16.0",
"husky": "^3.1.0"
}
}
```
按理来说,这种方式应该会和pre-commit库是一样的才对,但是,偏偏就是没反应,提示没有相应的hook用于执行,我猜想也可能是版本问题。
总体来说,大致的方法已经基本介绍完毕。
最后解答一下一开始针对装5.16.0版本的eslint,原因是eslint6目前似乎不是很稳定,不过仍待考察,可能是本人自己某些地方的失误。