我正在参加「掘金·启航计划」
从零开始的中大厂前端项目落地(二)
落地一个前端项目涉及非常多知识,因此从6个角度入手,化整为零,逐个击破:
- 选择合适的构建工具
- 定制团队代码规范
- 测试工具
- 封装自己的组件
- 自动部署
- 安全
定制团队代码规范
来到前端落地系列的第二篇,我们来看看是怎么定制团队规范的,会从以下三个方面逐一讲述:
- 校验工具
- 提交 git 规范
- 分支管理
检验工具
在一个多人协同的项目里,统一的规范对保证开发效率和代码质量至关重要。关于统一规范,社区已经存在大量实践和相关工具,相信同学们应该多少都接触过一些。接下来这一小节里,我们会从 eslint 和 prettier 开始,讲述这两个工具的应用。
eslint
eslint 在他的库写到:可以发现并修复你 JavaScript 代码中的问题。eslint 是一种用于识别和报告在 ECMAScript/JavaScript 代码中发现的模式的工具,其目标是使代码更加一致并避免错误。它是完全可插拔的。每条规则都是一个插件,您可以在运行时添加更多。您还可以添加社区插件、配置和解析器来扩展 eslint 的功能。
下面,我们把 eslint 运用到我们的项目里面。打开我们的项目,运行以下命令:
npm install --save-dev eslint
配置 eslint 有两种方式,
- 配置注释- 使用 JavaScript 注释将配置信息直接嵌入到文件中。
- 配置文件- 使用 JavaScript、JSON 或 YAML 文件指定整个目录及其所有子目录的配置信息。这可以是文件的形式
.eslintrc.*,也可以是文件eslintConfig中的字段package.json,ESLint 会自动查找和读取这两种形式,也可以在命令行指定配置文件。
这里特别说明一下,ESLint 支持以下几种格式的配置文件,如果同一目录下 .eslintrc 和 package.json 同时存在,.eslintrc 优先级高会被使用,package.json 文件将不会被使用:
- JavaScript - 使用
.eslintrc.js然后输出一个配置对象。 - YAML - 使用
.eslintrc.yaml或.eslintrc.yml去定义配置的结构。 - JSON - 使用
.eslintrc.json去定义配置的结构,ESLint的JSON文件允许 JavaScript 风格的注释。 - package.json - 在 package.json 里创建一个 eslintConfig属性,在那里定义你的配置。
如果同一个目录下有多个配置文件,ESLint 只会使用一个。优先级顺序如下:
- .eslintrc.js
- .eslintrc.yaml
- .eslintrc.yml
- .eslintrc.json
- .eslintrc
- 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"]
}
}
其中 semi 和 quotes 是 ESLint 中的代码规范配置,第一个值是规则的错误级别,可以是以下值之一:
"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安装插件使用的,下面我们来实操一下。
打开我们 vscode 的 settings.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 | 改进 | 改进功能,升级当前功能模块 |
一个好的提交规范示例:
分支管理
当我们初始化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 分支指向同一个提交节点
非快速合并的结果会在 master 分支上创建一个新的合并提交节点,并将 master分支指向新创建的提交节点
如果选择快速合并,则需要保证每个提交都是独立且完整的,如果不满足要求,Git 支持修改提交记录,需要修改后再次合并。
其他迭代
在创建当前分支之后,主分支可能又有新的提交,在合并之前,建议先将主分支新的提交合并到当前分支。
故障分支(正式环境紧急修复bug)
如果发现存在 Bug,就要尽快修复。此时,可以基于主分支新建故障分支,在验证没有问题后,故障分支需要合并回主分支,并在主分支上发布新的补丁版本。而主分支更新后,下游的公共分支要及时同步变更。
最后,让我们一起加油吧!