Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

前端工程化得到 2 种规范 #68

Open
Popxie opened this issue Aug 24, 2021 · 0 comments
Open

前端工程化得到 2 种规范 #68

Popxie opened this issue Aug 24, 2021 · 0 comments
Assignees

Comments

@Popxie
Copy link
Owner

Popxie commented Aug 24, 2021

前端工程化中的 2 种规范

涉及依赖简单介绍

  • husky: 用于创建 git hooks,并往 hooks 里添加要执行的脚本
  • lint-staged: 对改动的指定类型文件执行相应的脚本如 eslint!需配合 husky 使用,
  • commitizen(cz-cli): 一个 commit 脚手架,使用它时会经历一系列的问答生成固定格式的 commit,该格式同时也会被其他依赖库使用
  • conventional-changelog-cli: 读取 cz-cli 生成的特定格式 commit 结合 tag 标签生成固定格式的 CHANGELOG.md
  • commitlint: 检测人为手动提交 commit 时是否符合定制化的 rules 确保团队 commit 符合规范

1. 我的开发流程

在一个功能需求从 确认排期 => 开发 => 测试 => 上线 期间,这里按照不同阶段采取相应的 操作处理。这里以当前使用的 gitlab 仓库为例。

1.1 相关资料

先简单概述一下接下来要做的操作流程:

  • 确定排期 => 开发 => 测试 阶段: (GitLab, GitHub)

    • 创建 label(供 issueM(P)RMilestones 使用)
    • 创建 Milestones里程碑
    • 创建 issue
    • 创建 M(P)R
    • 关联 Milestones, 将 issue, M(P)R 归属到对应的 Milestones
  • 开发 => 测试 => 上线 阶段: (工程项目)

    • 创建符合规范的 commit
    • 生成 CHANGLOG.md
    • 更改 issue, M(P)Rlabel 状态

1.2 创建 & 关联

  • 创建 label
    这里主要分为 2 大种类(优先级, 状态) 以及 其他,如图所示:

    001

  • 创建 Milestones 里程碑

    里程碑的作用主要是盛放 issue, M(P)R,这里是以 月份的维度 进行划分的,一个里程碑表示一个月份.

    这么做也会有个好处,就是当你进行 KPI 自评的时候可以很清晰的知道自己做了什么东西,不然每回都要自己去翻阅邮件是一件比较蛋疼的事情!

    先来看一下 Milestones 外层:
    002

    再来看一下内层:
    003

  • 创建 issue

    一个 issue 代表一个功能,可能是新增功能也可能是 bug 修复也有可能是其他相关,issue 应该包 含相关需求 内容以及 相关人员。同时在创建期间请关联相关的 label, Milestones 以及 Assignee

    先来看一下 issue 外层:

    004

    再来看一下内层:

    005

  • 创建 M(P)R

    创建 M(P)R 的时机我认为不应该在准备上线阶段在创建,应该在分支推送到远端时就要创建,这样每回提交到远端以后就能及时 review 代码情况,发现问题及时处理。同时也能在队友之间了解一下整个项目的情况(当然这个重点不是在于监督对方!!!重点在于自检)等到自检完以后再把 MR 链接开放非队友 review.

    同上,创建 MR 的同时也要关联相关的 label, Milestones 以及 Assignee

    先来看一下外层:

    007

    再来看一下内层:

    006

小小建议

不知道发现没有,在 issue, Milestones 以及 MR 模块中都会有一个 Tis 必读label 相关提示?这里我是刻意而为之,里面给出了相关模块的规范说明,方便新人在创建相关模块数据的时候知道怎么创建怎么样做符合规范,以 MR 为例如下图:

008

小结

  • label 用于标记 issue & MR
  • issue & MR 含(关联)于 Milestones
  • 在创建 issue, MR, Milestones 时尽量给个类似 Tips 必读 的提示,方便新人

3.3 创建特定格式的 commit & 自动生成 CHANGELOG .md

上面已经提及了如何创建特定格式的 commit 了,那么在合并到 master 分支之前应该保证自己的分支 commit 记录符合规范且最后一个 commit 的类型为 chore。

然后根据特定格式的 commit 生成 CHANGELOG.md

  • 创建特定格式的 commit 格式如下:

    009

    从上可知 分为 2commits, 2commits+

  • 生成 CHANGELOG .md

    这里用到了conventional-changelog-cli,它的原理就是根据 cz-cli 创建的特殊格式的 commit 生成 CHANGELOG.md,相关操作看官网这里不做过多解释。

    先看看官网给的步骤:

    1. Make changes
    2. Commit those changes
    3. Make sure Travis turns green
    4. Bump version in package.json
    5. conventionalChangelog
    6. Commit package.json and CHANGELOG.md files
    7. Tag # 敲黑板!
    8.Push

Tips 如果不打 tag 每回生成的 CHANGELOG.md 都会包含之前的 commit 记录!

  • 最终效果如下图:

    010

  • 查看开源项目的 CHANGELOG & commit

    通过查看对比优秀的开源项目,即可发现 commit 提交的规范是什么,感兴趣的可以打开上面两个链接对比一下

    Tips conventional-changelog-cli 只会抓取 commit 类型为 feat fix perf revertcommit 生成 CHANGELOG.md,同时也说明 当要生成 CHANGELOG.md的时候意味着要修改版本号。

小结

  • 当需要更改版本号的时候才会用到 CHANGELOG.md,也意味着类型为 feat fix perf revertcommit跟版本号关联。其他类型则不需要更改版本号

2.代码规范

一个项目有多少人参与它就可能有多少种风格!光靠人为约束往往是不够的!!原因很简单,人会犯错,而程序不会犯!所以需要借助第三方库来实现这个代码风格统一!

2.1 相关资料

2.2 交给 eslint

发展至今 eslint 已经足够完善也足以满足很多团队的需要,所以没有必要重复造轮子,这里直接使用 eslint 统一代码风格。如果默认的满足不了你的需求,那就定制化规则~

2.3 全量 eslint & 定向 eslint & 部分 eslint

vue-cli3+ 生成的项目为例,项目 package.json 中的 scripts 下会有这么一段脚本

"scripts": {
  ···
  "lint": "vue-cli-service lint", // vue-cli3+ 自动添加的
  "lint-file": "vue-cli-service lint src/views", // 后来 自定义
  ···
},
  • 全量 eslint

    # 对当前项目全量eslint 耗时
    yarn lint || npm run lint
  • 定向 eslint

    # 自定义文件路径 对文件或者文件夹进行lint 相对来说耗时短 但是每回都这操作麻烦!
    yarn lint-file || npm run lint-file

    有没有更简单更快捷的方法?有!第三种

  • 部分 eslint (只对当前被更改的文件进行 eslint)

    这种情况就要用到了 husky, lint-staged 且触发时机是在提交 commit 之前进行触发。

    这里说一下主流程:

    • 安装 husky & 执行脚本

      # 注: 需要 npm 版本 Version 7.x已上(npm set-script 命令需要 7.x)
      npm set-script prepare "husky install" && npm run prepare
    • 添加 git hooks & 写入 lint-staged 脚本

      # 创建 pre-commit 且 写入 npx lint-staged 结果如下
      npx husky add .husky/pre-commit "npx lint-staged"
    • 安装 lint-staged & 设置参数

      # 安装
      npx mrm@2 lint-staged
      // package.json
      "lint-staged": {
        "*.{js,vue}": "eslint --fix" // 注意!{}中不可以有空格!!!
      }

      经过上述配置就可以实现每次执行 commit 的时候就会触发 pre-commit 钩子对 当前被更改的文件进行 eslint 格式化了。

如果你对默认的 eslint 规则不太满意那就直接修改规则,根据自己的项目定制化 eslint 规则~~,这里我使用了是其中一种文件格式yaml,

  • .eslintrc.yaml 部分内容如下:

    root: true
    env:
      browser: true
      es6: true
      node: true
    extends:
      - 'eslint:recommended'
      - 'plugin:vue/recommended'
    globals: {}
    
    parser: 'vue-eslint-parser'
    parserOptions:
      parser: babel-eslint
      ecmaVersion: 2020
      sourceType: module
    plugins:
      - vue # 支持.vue文件
    
    rules:
      eqeqeq: # 要求使用 === 和 !==
        - 2
        - always
      block-spacing: # 在块的开头和结尾之前必须使用空格 { xxx }
        - 2
        - always # 要求使用一个或多个空格
      semi:
        - 2
        - never # 禁止在语句末尾使用分号
      no-fallthrough:
        - 0
      keyword-spacing: # 强制在关键字前后使用一致的空格
        - 2
      space-before-function-paren: # 函数声明时括号与函数名间是否加空格
        - 2
        - anonymous: never
          named: never
          asyncArrow: always
      arrow-parens: # 箭头函数的参数是否使用圆括号
        - 2
        - as-needed # 必要时使用 圆括号
        - requireForBlockBody: true # 与as-needed搭配使用
    
      vue/max-len:
        - 2
        - code: 130 # js的非注释部的长度限制
          tabWidth: 2
          comments: 120 # js的注释部分 每一行的总长度,编辑器最左侧到代码最后一个位(包含空格)
      vue/html-indent:
        - 2
        - 2 # 几个缩进
        - attribute: 1 # 属性与 < 之间的缩进,1: 一个缩进
          baseIndent: 1 # html标签顶格缩进(0表示与template标签对其,1表示一个缩进)
          closeBracket: 0 # > 换行后 与 < 之间的缩进关系(设置了html-closing-bracket-newline后,当前属性无效)

2.4 小结

通过上述1.3这么一个操作,开发期间可以按照自己的风格去写代码,但是不管你怎么写,最终都会被 eslint 给强制格式化!这样就能保证主干分支 master 的代码风格统一!目的达到完美~

3. commit 规范

3.1 相关资料

3.2 commit 固定格式

关于这个固定格式我相信还是有一部分人是不知道的!在这里介绍一下:

# 原文
<type>[(<scope>)]: <description || subject> # header
# 空一行
[<body>] # body
# 空一行
[<footer(s)>] # footer
# 译文
<类型>[可选 范围||作用域]: <描述 || 主题>

[可选 正文]

[可选 脚注]

上述格式的 commit 我们可以直接通过 cz-cli 来生成,这就是为什么要引入这个 cz-cli 的原因。当然工具只是帮我们节省时间快速生成固定格式而已。手动生成也是可以的,就是效率可能没有工具那么高而已。

3.3 生成固定格式的 commit

  • 自动生成

    上文已经提及,自动生成需要接入 cz-cli 接下来简单的看看大概过程:

    • git add .

    • git cz 或 cz

      $ git cz
      [email protected], [email protected]
      
      # 1。选择类型
      ? Select the type of change that you are committing:
      ❯ feat:     A new feature
        fix:      A bug fix
        docs:     Documentation only changes
        style:    Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
        refactor: A code change that neither fixes a bug nor adds a feature
        perf:     A code change that improves performance
        test:     Adding missing tests or correcting existing tests
        chore:    Other changes that do not modify src or test files
        revert:   Reverts a previous commit
      
      # 2. 填写scope 这里我们统一使用当天日期 格式为 月-日 (带上0)必填
      ? What is the scope of this change (e.g. component or file name): (press enter to skip) 07-23
      # 3. 设置短标题 必填
      ? Write a short, imperative tense description of the change (max 87 chars): 我是短标题
      # 4. 设置长描述 选填, 填写之前 务必 搞已给缩进 防止 commit 过多的时候 眼花缭乱
      ? Provide a longer description of the change: (press enter to skip)
      # 5. 根据实际情况 选填
      ? Are there any breaking changes? (y/N)
      # 6. 根据实际情况 选填
      ? Does this change affect any open issues? (y/N)

    执行完已上操作以后就会生成如下格式的 commit 记录:

    commit 84253b3fb776f08692093573ae162599fec66f9d
    Author: KaKa_Xie <[email protected]>
    Date:   Tue Jul 20 21:25:55 2021 +0800
    
        feat(07-20): 抽离组件,代码优化         # <type>([scope]): <description>
    
        完成半通栏非通栏模块的开发自测           # [optional body]
    
        BREAKING CHANGE: 破坏性修改           # [optional footer(s)]
  • 手动生成

    • git add .

    • git com -m '<message>'

      # 注意 引号 开头,每按一个回车就会有个 quote>,
      $ git com -m 'feat(07-20): 做了什么新增功能
      quote>
      quote> 我是body
      quote>
      quote> 我是footer'
    • 看看结果

      commit ac7fa7256613571d95cffbc1e1a419312b7d07fa (HEAD -> feature/2021-08-25-word-optimize)
      Author: KaKa_Xie <[email protected]>
      Date:   Wed Aug 25 17:56:33 2021 +0800
      
      feat(07-20): 做了什么新增功能
      
      我是body
      
      我是footer

      总之不管你是 手动 生成还是借助 cz-cli 自动 生成,目的只有一个!就是生成特定格式的 commit 记录,为后面生成 CHANGELOG.md

另外关于 scope 作用域这个东西实在不知道命名,所以就直接使用了日期的格式已创建 commit 时的日期来定义。

3.4 防止他人跳过固定格式的 commit 约束!!!

上文有提及,人不是程序,人会犯错!为了避免 不规范的 commit 被提交到远端,此时需要接入commitlint

  • 安装 commitlint

    这里也会涉及 git hooks 所以也会用到 husky 文档里有介绍!

    npm install husky --save-dev
    # or
    yarn add husky --dev
    
    # Active hooks
    npx husky install
    # or
    yarn husky install
    
    # Add hook
    npx husky add .husky/commit-msg 'npx --no-install commitlint --edit $1'
    # or
    yarn husky add .husky/commit-msg 'yarn commitlint --edit $1'
    # 安装 commitlint
    npm install --save-dev @commitlint/{cli,config-conventional}
    # 生成配置文件
    echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
  • 设置 commitlint 的配置文件 commitlint.config.js

    这里需要说明一下,因为 cz-cli 已经自带了一些风格限制,为了避免人为直接使用 git commit 的风格跟 cz-cli 的不一样,所以 commitlint 的规则 得跟 cz-cli 保持一致

    const Configuration = {
      extends: ['@commitlint/config-conventional'],
      formatter: '@commitlint/format',
      rules: {
        // type 枚举类型
        'type-enum': [
          2,
          'always',
          [
            'feat',
            'fix',
            'docs',
            'style',
            'refactor',
            'perf',
            'test',
            'build',
            'ci',
            'chore',
            'revert'
          ]
        ],
        'header-max-length': [2, 'always', 94] // 与cz-li限制保持一致
      },
      defaultIgnores: true,
      helpUrl:
        'https://github.com/conventional-changelog/commitlint/#what-is-commitlint'
    }
    
    module.exports = Configuration
  • 查看效果

    $ git add .
    
    $ git com -m 我就不按规矩来怎么滴!
    ℹ No staged files match any configured task.
    ⧗   input: 我就不按规矩来怎么滴!
    ✖   subject may not be empty [subject-empty]
    ✖   type may not be empty [type-empty]
    
    ✖   found 2 problems, 0 warnings
    ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
    
    husky - commit-msg hook exited with code 1 (error)

3.5 总结

  • 生成固定格式的 commit 有两种方式

    • 自动生成:省时省力
    • 手动生成:费时费力
  • 防止通过正常 git commit 提交不符合固定格式的 commit

    • 使用 commitlint

总之上述操作就是为了生成固定格式的 commit

@Popxie Popxie closed this as completed Aug 24, 2021
@Popxie Popxie self-assigned this Aug 24, 2021
@Popxie Popxie changed the title 【占位issue】 前端工程化得到 3 种规范 Aug 25, 2021
@Popxie Popxie reopened this Aug 25, 2021
@Popxie Popxie changed the title 前端工程化得到 3 种规范 前端工程化得到 2 种规范 Aug 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant