从零开始的中大厂前端项目落地(二)

1,295 阅读10分钟

我正在参加「掘金·启航计划」

从零开始的中大厂前端项目落地(二)

落地一个前端项目涉及非常多知识,因此从6个角度入手,化整为零,逐个击破:

  1. 选择合适的构建工具
  2. 定制团队代码规范
  3. 测试工具
  4. 封装自己的组件
  5. 自动部署
  6. 安全


定制团队代码规范

来到前端落地系列的第二篇,我们来看看是怎么定制团队规范的,会从以下三个方面逐一讲述:

  • 校验工具
  • 提交 git 规范
  • 分支管理


检验工具

在一个多人协同的项目里,统一的规范对保证开发效率和代码质量至关重要。关于统一规范,社区已经存在大量实践和相关工具,相信同学们应该多少都接触过一些。接下来这一小节里,我们会从 eslintprettier 开始,讲述这两个工具的应用。

eslint

eslint 在他的库写到:可以发现并修复你 JavaScript 代码中的问题。eslint 是一种用于识别和报告在 ECMAScript/JavaScript 代码中发现的模式的工具,其目标是使代码更加一致并避免错误。它是完全可插拔的。每条规则都是一个插件,您可以在运行时添加更多。您还可以添加社区插件、配置和解析器来扩展 eslint 的功能。

下面,我们把 eslint 运用到我们的项目里面。打开我们的项目,运行以下命令:

npm install --save-dev eslint

配置 eslint 有两种方式,

  • 配置注释- 使用 JavaScript 注释将配置信息直接嵌入到文件中。
  • 配置文件- 使用 JavaScript、JSON 或 YAML 文件指定整个目录及其所有子目录的配置信息。这可以是文件的形式 .eslintrc.* ,也可以是文件 eslintConfig 中的字段 package.json ,ESLint 会自动查找和读取这两种形式,也可以在命令行指定配置文件。

这里特别说明一下,ESLint 支持以下几种格式的配置文件,如果同一目录下 .eslintrcpackage.json 同时存在,.eslintrc 优先级高会被使用,package.json 文件将不会被使用:

  • JavaScript - 使用 .eslintrc.js 然后输出一个配置对象。
  • YAML - 使用 .eslintrc.yaml.eslintrc.yml 去定义配置的结构。
  • JSON - 使用 .eslintrc.json 去定义配置的结构,ESLintJSON 文件允许 JavaScript 风格的注释。
  • package.json - 在 package.json 里创建一个 eslintConfig属性,在那里定义你的配置。

如果同一个目录下有多个配置文件,ESLint 只会使用一个。优先级顺序如下:

  1. .eslintrc.js
  2. .eslintrc.yaml
  3. .eslintrc.yml
  4. .eslintrc.json
  5. .eslintrc
  6. package.json

ESLint 还支持层叠配置,层叠配置使用离要检测的文件最近的 .eslintrc文件作为最高优先级,然后才是父目录里的配置文件:

默认情况下,ESLint 会在所有父级目录里寻找配置文件,一直到根目录,子目录内的配置规则优先级高于父目录,与父目录规则冲突时将覆盖父目录的规则。

需要将 ESLint 限制到一个特定的项目、目录时,可以在项目根目录下的 package.json 文件或者 .eslintrc.* 文件里的 eslintConfig 字段下设置 "root": true。ESLint 一旦发现配置文件中有 "root": true,它就会停止在父级目录中寻找。

然后我们创建项目的 .eslintrc.js 文件

npm init @eslint/config

执行以上命令后,会有 eslint 配置预选,填好所有信息后会增加一个 .eslintrc.js 文件,打开后发现文件里已经有一些默认配置代码:

{
    "rules": {
        "semi": ["error", "always"],
        "quotes": ["error", "double"]
    }
}

其中 semiquotesESLint 中的代码规范配置,第一个值是规则的错误级别,可以是以下值之一:

  • "off"0- 关闭规则
  • "warn"1- 打开规则作为警告(不影响退出代码)
  • "error"2- 将规则作为错误打开(退出代码将为 1)

最后可以通过在项目根目录创建一个 .eslintignore 文件告诉 ESLint 去忽略特定的文件和目录。.eslintignore 文件是一个纯文本文件,其中的每一行都是一个 glob 模式表明哪些路径应该忽略检测。

当 ESLint 运行时,在确定哪些文件要检测之前,它会在当前工作目录中查找一个 .eslintignore 文件。如果发现了这个文件,当遍历目录时,将会应用这些默认设置。一次只有一个 .eslintignore 文件会被使用,所以,不是当前工作目录下的 .eslintignore 文件将不会被用到。

Globs 匹配使用 node-ignore,所以大量可用的特性有:

  • # 开头的行被当作注释,不影响忽略模式。
  • 路径是相对于 .eslintignore 的位置或当前工作目录。通过 --ignore-pattern command 传递的路径也是如此。
  • 忽略模式同 .gitignore 规范
  • 以 ! 开头的行是否定模式,它将会重新包含一个之前被忽略的模式。
  • 忽略模式依照 .gitignore 规范.

下面是github上某个高星项目使用的 .eslintrc 配置,内容可供我们参考,


module.exports = {
  parser: '@typescript-eslint/parser',
  parserOptions: {
    sourceType: 'module'
  },
  plugins: ['jest'],
  rules: {
    'no-debugger': 'error',
    'no-unused-vars': [
      'error',
      // we are only using this rule to check for unused arguments since TS
      // catches unused variables but not args.
      { varsIgnorePattern: '.*', args: 'none' }
    ],
    // most of the codebase are expected to be env agnostic
    'no-restricted-globals': ['error', ...DOMGlobals, ...NodeGlobals],

    'no-restricted-syntax': [
      'error',
      // since we target ES2015 for baseline support, we need to forbid object
      // rest spread usage in destructure as it compiles into a verbose helper.
      'ObjectPattern > RestElement',
      // tsc compiles assignment spread into Object.assign() calls, but esbuild
      // still generates verbose helpers, so spread assignment is also prohiboted
      'ObjectExpression > SpreadElement',
      'AwaitExpression'
    ]
  },
  overrides: [
    // tests, no restrictions (runs in Node / jest with jsdom)
    {
      files: ['**/__tests__/**', 'packages/dts-test/**'],
      rules: {
        'no-restricted-globals': 'off',
        'no-restricted-syntax': 'off',
        'jest/no-disabled-tests': 'error',
        'jest/no-focused-tests': 'error'
      }
    },
    // ...
    // 
    // ...
    // Node scripts
    {
      files: [
        'scripts/**',
        './*.js',
        'packages/**/index.js',
        'packages/size-check/**'
      ],
      rules: {
        'no-restricted-globals': 'off',
        'no-restricted-syntax': 'off'
      }
    }
  ]
}


prettier

prettier 的作用是对代码进行格式化,并不关注代码质量潜在问题的检查。

prettier 自身的规范倾向于团队的代码风格的规范或统一,例如每行最大长度,单引号还是双引号,等号左右空格,使用 tab 还是 空格 等等。

很多人的 prettier 是直接在vscode安装插件使用的,下面我们来实操一下。

打开我们 vscodesettings.json

    {  
        "editor.defaultFormatter": "esbenp.prettier-vscode",  
        "[javascript]": {  
            "editor.defaultFormatter": "esbenp.prettier-vscode"  
        }  
    }

这时候我们键入 CMD/CTRL + Shift + P 就能将当前文件格式化了,但是这样还是比较麻烦。 prettier 还可以开启代码保存自动格式化功能,只要配置加上 "prettier.requireConfig": true ,这样就能再我们保存的时候触发格式化了。

prettier 插件获取配置文件有一个优先级:.prettierrc > .editorconfig > vscode默认配置

如果你想在特定语言上禁用pretty,你可以创建一个.prettierignore文件,或者你可以使用VS Code的editor.defaultFormatter设置。



提交 git 规范

管理项目版本通常会选择使用Git,它可敏捷高效地处理任何项目。毕竟Git是世界上目前最先进的分布式版本控制系统内容管理系统了。

想要用好Git并不容易,因为在使用Git托管代码时,很多同学喜欢命令行编程,这样每次提交都必须书写Commit Message。规范的Message不仅能帮助别人Review ,还能有效地输出Changelog,甚至对项目的Quality都有很大提升。

在日常开发中经常遇到一些千奇百怪的提交说明,例如中英文混合使用、各种不规范的英文单词等。这让Review这些提交说明时会经常搞不清它们到底是干哈的,导致后续代码维护成本巨大。

要想你的前端工程化项目更易于维护,最好有一套Git提交说明的规范化模板。本章将带领你部署Git的提交格式化,通过交互式问答生成提交模板,让提交规范更好地服务代码质量,以提升开发效率。

类型功能描述
feat功能新增功能,迭代项目需求
fix修复修复缺陷,修复上一版本存在问题
docs文档更新文档,仅修改文档不修改代码
style样式变动格式,不影响代码逻辑
refactor重构重构代码,非新增功能也非修复缺陷
perf性能优化性能,提高代码执行性能
test测试新增测试,追加测试用例验证代码
build构建更新构建,改动构建工具或外部依赖
ci脚本更新脚本,改动CI或执行脚本配置
chore事务变动事务,改动其他不影响代码的事务
revert回滚回滚版本,撤销某次代码提交
merge合并合并分支,合并分支代码到其他分支
sync同步同步分支,同步分支代码到其他分支
impr改进改进功能,升级当前功能模块

一个好的提交规范示例:

企业微信截图_16769491256345.png



分支管理

当我们初始化Git仓库的时候,Git会默认创建一个名为master的主分支。在实际工作中,主分支要求是一个稳定、健壮、安全的主线,一般不允许在主分支上直接进行开发,而是拉取一个新的分支,开发、测试完成后,再将分支合并到主分支上。

使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录的完整副本,对大型项目来说会花费很长时间。

功能分支

当有新的功能要开发时,应该新建一个功能分支,在 git Bash 输入:

git checkout -b feature/a

当有新的功能、新的迭代就新建一个迭代分支,新的迭代分支可以从 master 分支 checkout 出来,或者如果你们公司有预发布分支的话就可以在预发布分支 checkout。这样做的目的在于,新迭代开发,保持在最新的代码环境下。

当我们做完某一个迭代,并且测试通过,要上线时,合并回主分支有两种选择,即快速合并和非快速合并,二者的区别在于是否创建提交节点,命令如下

git merge feature/a #快速合并

git merge --no-ff feature/a #非快速合并

快速合并的结果会直接将 master 分支和 feature/a 分支指向同一个提交节点

企业微信截图_1676947413829.png

非快速合并的结果会在 master 分支上创建一个新的合并提交节点,并将 master分支指向新创建的提交节点

企业微信截图_16769473703752.png

如果选择快速合并,则需要保证每个提交都是独立且完整的,如果不满足要求,Git 支持修改提交记录,需要修改后再次合并。

其他迭代

在创建当前分支之后,主分支可能又有新的提交,在合并之前,建议先将主分支新的提交合并到当前分支。

企业微信截图_16769475213676.png

企业微信截图_1676947872969.png

故障分支(正式环境紧急修复bug)

如果发现存在 Bug,就要尽快修复。此时,可以基于主分支新建故障分支,在验证没有问题后,故障分支需要合并回主分支,并在主分支上发布新的补丁版本。而主分支更新后,下游的公共分支要及时同步变更。

企业微信截图_16769486302273.png



最后,让我们一起加油吧!

gg.jpg