乐趣区

关于代码规范:完全理解如何统一项目中的代码风格

对代码进行格式化,是程序员的日常。格式化很爽,然而配置相干的规定、装置对应插件却很烦。与其每次碰到问题再缓缓排查,不如一次性死记硬背。

一、代码格调是什么(Code Conventions)

咱们能够依照 批改后是否会影响程序运行后果 来把 格调 分为两个局部。例如上面的代码

var a= 1;
if (a=='1') console.log(true)

1. Format 格局 -> format 格式化(首字母大小写以便辨别)

格局,简略来说就是变量前面是否须要空格,语句前面是否须要分号等,这一类无论如何改变,都不会影响代码运行后果的局部。对 格局 进行扭转叫 格式化

应用如下规定对代码进行 format:

  • 语句之后必须接分号
  • 括号头尾须要 1 个空格
  • 运算符前后须要 1 个空格
var a = 1;
if (a == '1') console.log(true);

2. Source 源码 ->(source action 源动作)

源码,与格局绝对的,是被批改之后会切实影响代码运行后果的局部。对 源码 进行扭转叫 源动作

应用如下规定对代码进行 source action:

  • 未产生扭转的变量必须应用 const 定义
  • 必须应用 ===,禁止应用 ==
const a = 1;
if (a === '1') console.log(true);

格局加源码,形成了代码格调

定义起源:vscode 任意选中一段代码之后右键

二、格调工具

格调当然是有各种各样的,有的工具能够设定本人的格调,有的工具强制应用特定格调。为了便于了解,本文只介绍业界最支流的工具(也很少有人用其余的)

Prettier

Prettier 专一于 Format,根本反对了前端我的项目相干的所有文件类型,包含但不限于

  • JavaScript
  • JSX
  • Vue
  • TypeScript
  • CSS、Less、SCSS
  • HTML
  • JSON
  • Markdown

Prettier 最大的特点是 独裁 ,在本身规定的几百上千条 Format 规定中,可配置的仅有 20 条。这也导致 其余工具与 Prettier 并存时,都须要迁就 Prettier 的规定

ESLint

ESLint 是目前所有 Lint 工具中应用最宽泛的(前端范畴内)。

计算机科学中,lint 是一种工具程序的名称,它用来标记源代码中,某些可疑的、不具结构性(可能造成 bug)的段落。它是一种动态程序剖析工具,最早实用于 C 语言,在 UNIX 平台上开发进去。起初它成为通用术语,可用于形容在任何一种计算机程序语言中,用来标记源代码中有疑义段落的工具。
—— wiki

ESlint 可配置的范畴,包含 Format 和 Source,然而 仅限于 能够被转换成 AST 的代码,对于 CSS、HTML 等都无能为力(这也是为什么须要同时应用 ESLint 和 Prettier 的起因)

stylelint

前端开发根本等同于 HTML、JavaScript 和 CSS 开发。通过 Prettier + ESLint,对于格调中的 Format 曾经齐全对立,JavaScript 中的 Source 也被对立。所以当初还剩下根本能够疏忽的 HTML 和 CSS 中的 Source 局部

咱们抉择应用 stylelint 来解决 CSS 相干 Source

这样根本能够限定前端开发过程中的所有格调

HTML JavaScript CSS
Format prettier prettier prettier
Source ESlint stylelint

三、应用阐明

通常我的项目中应用格调工具,有三种路径

  • A – 编译器引入相干插件
  • B – webpack 引入相干 loader、plugin
  • C – 命令行间接执行

先模仿一下我的项目中开发需要的流程

  1. 拉取我的项目代码,装置依赖,初始化我的项目配置格调设置,命令行格式化所有代码(C)
  2. 应用 webpack 编译我的项目

    1. 窗口中及时提醒格调问题并主动修复(A)
    2. 控制台及时提醒格调问题,不修改状况下打包失败(B)
  3. 应用 git 提交,触发钩子,查看格调通过之后才容许提交(C)

任何流程没有管制住,都有可能造成设定以外的代码格调

无论是通过函数、命令行或者插件来应用,风格化的过程根本都能够形象为如下公式。

Result = format(sourceAction(src, config)) = Tool(src, config)
// 最终格调 = 格式化(源动作(源码,配置)) = 工具(源码,配置)

源码为常量。只有保障工具版本对立,配置雷同,则不同路径均也能够得出雷同的后果。规定和工具的抉择从来不是难点,难点在于保障工具、配置的对立

接下来介绍如何保障 A、B、C 三种路径的对立

A – 编译器引入相干插件

工具

ESlint: The extension uses the ESLint library installed in the opened workspace folder. If the folder doesn’t provide one the extension looks for a global install version.

Prettier: This extension will use prettier from your project’s local dependencies (recommended)…

stylelint: The extension uses the stylelint library installed in the opened workspace folder…

依据各个工具的官网插件文档阐明,插件会优先应用我的项目中的对应库 node_modules,如果不存在则应用全局库。

配置

ESLint

ESLint 插件目前能够指定配置文件,如果不指定会读取 package.json 同级的配置文件

eslint.options: options to configure how ESLint is started using the ESLint CLI Engine API. Defaults to an empty option bag. An example to point to a custom .eslintrc.json file is:

{"eslint.options": { "configFile": "C:/mydirectory/.eslintrc.json"}
}

Prettier

Prettier 的配置能够来源于三处,按优先级排列

  1. Prettier configuration file
  2. .editorconfig
  3. Visual Studio Code Settings (Ignored if any other configuration is present)

理论应用中,应用第一个  package.json 同级的配置文件即可

stylelint

与 Prettier 相似

B – webpack 引入相干 loader、plugin

const StyleLintPluginfrom = require('stylelint-webpack-plugin');
//...  
{test: /\.(j|t)sx?$/,
        use: [
          {loader: 'babel-loader',},
          {
            loader: 'eslint-loader',
            options: {configFile: getWorkSpacePath('.eslintrc.js'),
            }
          },
        ],
  }
//...
plugins: [
    new StyleLintPluginfrom({configFile: getWorkSpacePath('.stylelintrc.js'),
    })
]
//...

工具

所有库都须要装置在我的项目的 node_modules 中,eslint-loader 同时依赖于 eslint 库(stylelint-webpack-plugin 相似)

配置

所有工具根本都能够在 option 中指定配置文件

C – 命令行间接执行

工具

首先须要在 node_modules 中装置有对应的库,而后在 package.json 中设置对应脚本

{
  //...
    "scripts": {
        "eslint": "eslint",
        "prettier": "prettier",
        "stylelint": "stylelint",
    },
  //...
}

之后能够在命令行中应用

yarn eslint --fix
-c, --config path::String      Use this configuration, overriding .eslintrc.* config options if present

yarn prettier --write
--config ./my/.prettierrc

yarn stylelint --fix
--config ./my/.stylelintrc

配置

所有工具在应用均能够指定配置文件

所以

  • 工具对立等价于 把相干依赖全副装置到我的项目 **node_modules**,保障不应用全局依赖
  • 配置对立等价于应用对立的配置文件。因为局部插件不能指定门路,只会默认读取 node_modules 同级,所以倡议所以配置文件都放在这一层

四、实战

首先引入 Prettier,咱们所有的 format 都应用 Prettier 来实现。

在我的项目中接入 Prettier

yarn add prettier -D

1. 装置插件

装置官网举荐的编译器插件 Prettier - Code formatter(此处只思考 VSCode),设置工作区的 .vscode/setting.json

切记肯定要敞开其余带有格式化性能的插件,否则会发生冲突。特地是应用 VUE 框架时,记得敞开 vetur 的格式化。同时记得检查一下全局范畴的 setting.json,正文掉所有 format 相干的配置

{ 
    // 保留时主动 Format
  "editor.formatOnSave": true,
    // 敞开 vetur 格式化
  "vetur.format.enable": false,
}

2. 举荐插件

为了通知其余协同开发的共事,装置正确的 Prettier 插件,增加插件名在 .vscode/extensions.json 中,同时把其余容易烦扰格式化的插件设置为不举荐。

这样其他人在首次装置我的项目的同时也会收到对应的提醒了。

{
  "recommendations": ["esbenp.prettier-vscode",],
  "unwantedRecommendations": ["hookyqr.beautify"]
}

 

3. 配置文件

package.json 同级创立 Prettier 的配置文件

// prettier.config.js or .prettierrc.js
module.exports = {
  trailingComma: "es5",
  tabWidth: 4,
  semi: false,
  singleQuote: true,
};

git 提交本次批改(尤其是 .vscode 文件夹)。之后任何人开发这个我的项目,只有装置了正确的插件,写进去的代码格调必定都是对立的了

4. 限度提交

假如有一个共事头铁,就是不正确装置插件和配置编译器。他提交代码的格调就无奈失去对立,所以须要再减少一层保险,在 git commit 时候须要校验所有改变过的文件,对这些文件应用 prettier --write

git commit 时触发、校验所有改变过的文件。这两个性能别离是两个插件

  • husky 

它能运行 Githooks 诸如 Pre-commit、pre-receive 和 post-receive。

用以在各个阶段触发不同校验,个别配合各种 lint 应用

  • lint-staged 

当我的项目文件比拟多的时候,如果每次改变都对所有文件进行校验。势必导致等待时间变长。解决下面的痛点就须要应用 lint-staged。它只会校验你提交或者说你批改的局部内容。

yarn add husky lint-staged -D

package.json 中增加字段

 "husky": {
    "hooks": {"pre-commit": "lint-staged"}
  },
  "lint-staged": {
    // src 目录下任意文件有改变,都应用 prettier --write 格式化之后再提交
    "src/**/*.*": [
      "prettier --write",
      "git add"
    ]
  }

这样根本就能保障我的项目的十拿九稳了(一失在于开发者删除 husky、lint-stage 配置????‍♂️)

在我的项目中接入 ESLint、stylelint

Prettier 只提供了格调中 Format 的局部,对于 Source,还须要接入其余工具。

  • ESLint:解决 JavaScript 相干(TypeScript、JSX …)的 Source action
  • stylelint:解决 CSS 相干 (Less、SCSS) 的 Source action

流程根本和接入 Prettier 一样

1. 装置、举荐插件

装置 ESLint stylelint,并批改 setting.json

yarn add eslint stylelint -D

留神 formatOnSavecodeActionsOnSave 两者的区别。之前说过,由 Prettier 进行所有的 format,而后再针对不同类型的文件应用各种的 Soruce action

相干探讨:https://github.com/microsoft/vscode/issues/87096#issuecomment-567750791

{ 
  // 保留时主动 Format
  "editor.formatOnSave": true,
    
  // 保留时主动 Source action
  "editor.codeActionsOnSave": {
    "source.fixAll": true, // 开启所有工具的 source action
    //"source.fixAll.eslint": true, // 开启 ESLint 的 source action
    //"source.fixAll.stylelint": true, // 开启 stylelint 的 source action
  },
  "vetur.format.enable": false,
}

批改 extensions.json

{
  "recommendations": [
    "esbenp.prettier-vscode",
    "dbaeumer.vscode-eslint",
    "stylelint.vscode-stylelint"
  ],
  "unwantedRecommendations": ["hookyqr.beautify"]
}

2. 配置文件

package.json 同级创立 ESlint、stylelint 的配置文件,具体如何设置此处就不阐明了。要留神的就是肯定要 给 Prettier 的设置让位
**
给 ESLint、stylelint 装置兼容 prettier 的插件 

yarn add eslint-config-prettier stylelint-config-prettier -D
// .eslintrc.js
module.exports = {
  //...
  env: {
    browser: true,
    es6: true,
  },
  
  extends: ["eslint:recommended", "prettier"],
  plugins: [],
  rules: {},
  //...
};
// .stylelintrc.js
module.exports = {
  //...
  extends: ["stylelint-config-prettier"],
  plugins: [],
  rules: {},
  //...
};

3. 编译校验

很多 Source 问题会要求用户手动更改,所以须要及时提醒。插件尽管会提醒,但不会影响代码编译后果,所以须要在编译过程中校验

详见之前的 B – webpack 引入相干 loader、plugin 段落

4. 限度提交

批改 package.json

 "husky": {
    "hooks": {"pre-commit": "lint-staged"}
  },
  "lint-staged": {
    // src 目录下任意文件有改变,都应用 prettier --write 格式化之后再提交
    "src/**/*.js": [
      "eslint --fix",
      "prettier --write",
      "git add"
    ],
    "src/**/*.css":[
      "stylelint --fix",
      "prettier --write",
      "git add"
    ]
  }

至此,格调对立相干的所有流程都曾经笼罩到了!

附录

退出移动版