本文以 React Native 项目为示例介绍了前端规范化开发涉及的工具及知识,但是所涉及内容具有通用性,建议读者点赞收藏(^▽^)。
另外安利一下 @sigmayun/react-native-template-typescript ,这是一个基于 typescript 的 react native 开箱即用的模板。本文所涉及的大部分内容都集成到了该模板中。
gitconfig 1 2 3 4 5 6 7 8 9 $ git config --global user.name 'your_name' $ git config --global user.email 'your_email@aliyun.com' $ git config --global color.ui auto $ git config --global credential.helper store $ git config --global core.autocrlf input
以上配置内容可以在 ~/.gitconfig
文件中找到。
npm scripts package.json
文件的 scripts 字段是定义可执行脚本用的,可以利用它来实现简单的工作流。如果不是大型的项目,不建议使用 gulp,npm scripts 一样可以完成工作流设计的任务。下面是 React Native 项目默认的 scripts,如今我们可以把使用和扩展 scripts 看做是前端基本功。
1 2 3 4 5 6 7 8 9 { "scripts" : { "android" : "react-native run-android" , "ios" : "react-native run-ios" , "start" : "react-native start" , "test" : "jest" , "lint" : "eslint ." } }
使用 EditorConfig 实现跨编辑器代码风格统一 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # EditorConfig is awesome: http://EditorConfig.org # top-most EditorConfig file root = true # Unix-style newlines with a newline ending every file [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false [*.gradle] indent_size = 4 [BUCK] indent_size = 4
使用ESLint规范代码 作者自己团队的 ESLint 方案是基于 eslint-config-airbnb 扩展的,有兴趣可以体验一下 @sishuguojixuefu/eslint-config
安装依赖 1 2 3 4 5 6 7 8 9 10 11 $ yarn global add install-peerdeps $ install-peerdeps -D eslint-config-airbnb $ yarn add -D eslint-plugin-react-native $ yarn add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-import-resolver-typescript typescript $ yarn add -D prettier eslint-plugin-prettier eslint-config-prettier $ yarn add -D eslint-plugin-promise eslint-plugin-you-dont-need-lodash-underscore eslint-plugin-you-dont-need-momentjs
package.json 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 { "eslintConfig" : { "extends" : [ "airbnb" , "airbnb/hooks" , "plugin:react-native/all" , "plugin:@typescript-eslint/recommended" , "plugin:promise/recommended" , "plugin:you-dont-need-lodash-underscore/compatible" , "plugin:you-dont-need-momentjs/recommended" , "plugin:prettier/recommended" , "prettier" , "prettier/react" , "prettier/@typescript-eslint" ] , "env" : { "react-native/react-native" : true } , "parser" : "@typescript-eslint/parser" , "parserOptions" : { "ecmaFeatures" : { "jsx" : true } } , "settings" : { "import/extensions" : [ ".js" , ".ts" , ".tsx" ] , "import/resolver" : { "typescript" : { "alwaysTryTypes" : true } } } } }
.prettierrc.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 module .exports = { printWidth : 150 , tabWidth : 2 , useTabs : false , semi : false , trailingComma : 'es5' , singleQuote : true , bracketSpacing : true , jsxBracketSameLine : false , arrowParens : 'avoid' , vueIndentScriptAndStyle : false , endOfLine : 'lf' , }
插件介绍 eslint-config-airbnb: 该软件包提供 Airbnb 的 .eslintrc 作为可扩展的共享配置 eslint-plugin-react-native: 针对 ESLint 的 React Native 特定 linting 规则 @typescript-eslint/parser: 将 TypeScript 转换为 ESTree,使 eslint 可以识别 @typescript-eslint/eslint-plugin: 一个包含一堆特定于 TypeScript 的 ESLint 规则的插件 eslint-import-resolver-typescript: 给 eslint-plugin-import 添加 typescript 支持的插件 eslint-plugin-prettier: 以 ESLint 插件的形式运行 prettier eslint-config-prettier: 关闭所有不必要或可能与 prettier 的规则冲突的 ESLint 规则。一定要放到最后。 vscode eslint plugin config 1 2 3 4 5 6 7 8 9 10 11 12 13 14 "editor.codeActionsOnSave" : { "source.fixAll.eslint" : true } , "eslint.lintTask.enable" : true , "eslint.packageManager" : "yarn" , "eslint.alwaysShowStatus" : true , "eslint.validate" : [ "javascript" , "javascriptreact" , "typescript" , "typescriptreact" , "vue" , "html" ]
用 husky 和 lint-staged 构建超溜的代码检查工作流 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 { "husky" : { "hooks" : { "pre-commit" : "tsc --noEmit && lint-staged" } } , "lint-staged" : { "**/*.{js,jsx,ts,tsx}" : [ "eslint --fix" , "git add" ] , "**/*.{md,json}" : [ "prettier --write" , "git add" ] } }
Conventional Commits 约定式提交规范 Conventional Commits 是一种用于给提交信息增加人机可读含义的规范。约定式提交规范是一种基于消息的轻量级约定。它提供了一组用于创建清晰的提交历史的简单规则;这使得编写基于规范的自动化工具变得更容易。这个约定与 SemVer 相吻合,在提交信息中描述新特性、bug 修复和破坏性变更。
提交说明的结构如下所示:
1 2 3 4 5 <类型>([可选的作用域]): <描述> [可选的正文] [可选的脚注]
类型 build:
: 影响构建系统或外部依赖关系的更改(示例范围:gulp、broccoli、NPM)。chore:
: 其他不修改src
或test
文件。ci:
: 更改持续集成文件和脚本(示例范围:Travis、Circle、BrowserStack、SauceLabs)。docs:
: 只是更改文档。feat:
: 类型为 feat
的提交表示在代码库中新增了一个功能(这和语义化版本中的 MINOR
相对应)。fix:
:类型为 fix
的 提交表示在代码库中修复了一个 bug (这和语义化版本中的 PATCH
相对应)。improvement:
: 用于对当前实现进行改进而没有添加新功能或修复错误的提交。perf:
: 改进性能的代码更改。refactor:
: 代码重构,既不修复错误也不添加功能。revert:
: commit 回退。style:
: 不影响代码含义的变化(空白、格式化、缺少分号等)。test:
: 添加确实测试或更正现有的测试。范围 可以为提交类型添加一个围在圆括号内的作用域,以为其提供额外的上下文信息。例如 feat(parser): adds ability to parse arrays.
。
BREAKING CHANGE 在可选的正文或脚注的起始位置带有 BREAKING CHANGE:
的提交,表示引入了破坏性 API 变更(这和语义化版本中的 MAJOR
相对应)。 破坏性变更可以是任意 类型 提交的一部分。
示例 包含了描述以及正文内有破坏性变更的提交说明 1 2 3 feat: allow provided config object to extend other configs BREAKING CHANGE: `extends` key in config file is now used for extending other config files
包含了可选的 !
字符以提醒注意破坏性变更的提交说明 1 2 3 chore!: drop Node 6 from testing matrix BREAKING CHANGE: dropping Node 6 which hits end of life in April
不包含正文的提交说明 1 docs: correct spelling of CHANGELOG
包含作用域的提交说明 1 feat(lang): add polish language
为 fix 编写的提交说明,包含(可选的) issue 编号 1 2 3 4 5 fix: correct minor typos in code see the issue for details on the typos fixed closes issue #12
约定式提交规范 每个提交都必须 使用类型字段前缀,它由一个名词组成,诸如feat
或fix
,其后接一个可选的 作用域字段,以及一个必要的 冒号(英文半角)和空格。 当一个提交为应用或类库实现了新特性时,必须 使用feat
类型。 当一个提交为应用修复 bug 时,必须 使用fix
类型。 作用域字段可以跟随在类型字段后面。作用有必须 是一个描述某部分代码的名词,并用圆括号包围,例如:fix(parser):
描述字段必须 紧接在类型/作用域前缀的空格之后。描述指的是对代码变更的简短总结,例如:fix:array parsing issue when multiplejspaces were contained in string
。 在简短描述之后,可以 编写更长的提交正文,为代码变更提供额外的上下文信息。正文必须 起始于描述字段结束的一个空行后。 在正文结束的一个空行之后,可以 编写一行或或多行脚注。脚注必须 包含关于提交的元信息,例如:关联的合并请求、Reviewer、破坏性变更、每条元信息一行。 破坏性变更必须 标示在正文区域最开始处,或脚注区域中某一行的开始。一个破坏性变更必须 包含大写的文本BREAKING CHANGE
,后面紧跟冒号和空格。 在BREAKING CHANGE:
之后必须 提供描述,以描述对 API 的变更。例如:BREAKING CHANGE: environment variables now take precedence over config files
。 在提交说明中,可以 使用feat
和fix
之外的类型。 工具的实现必须不 区分大小写地解析构成约定式提交的信息单元,只有BREAKING CHANGE
必须 是大写的。 可以 在类型/作用域前缀之后,:
之前,附加!
字符,以进一步提醒注意破坏性变更。当有!
前缀时,正文或脚注内必须包含BREAKING CHANGE: description
为什么使用约定式提交 自动化生产 CHANGELOG。 基于提交的类型,自动决定语义化的版本变更。 向同事、公众与其他利益关系者传达变化的性质。 触发构建和部署流程。 让人们探索一个更加结构化的提交历史,以便降低对你的项目作出贡献的难度。 commitlint commitlint检查您的提交消息是否符合conventional commit format 。
1 2 $ yarn add -D @commitlint/cli @commitlint/config-conventional @commitlint/prompt-cli $ yarn add -D husky lint-staged
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { "scripts" : { "commit" : "commit" } , "commitlint" : { "extends" : [ "@commitlint/config-conventional" ] } , "husky" : { "hooks" : { "commit-msg" : "commitlint -E HUSKY_GIT_PARAMS" } } }
standard-version standard-version 是一款遵循语义化版本( semver) 和 commit message 标准规范 的版本和 changlog 自动化工具。通常情况线下,我们会在 master 分支进行如下的版本发布操作:
git pull origin master
根据 package.json
中的 version
更新版本号,更新 CHANGELOG git add .
git commit
git tag
打版本操作git push --follow-tags origin master && npm publish
:push 版本 tag 和 master 分支到仓库并发布其中 2,3,4,5 是 standard-version 工具会自动完成的工作,配合本地的 shell 脚本,则可以自动完成一系列版本发布的工作了。
安装 & 使用 1 $ yarn add -D standard-version
1 2 3 4 5 6 { "scripts" : { "release" : "standard-version" } }
First Release:yarn release --first-release
Cutting Release:yarn release
Release as a Pre-Release:yarn release --prerelease
or yarn release --prerelease alpha
Release as a Target Type Imperatively (npm version
-like):yarn release --release-as minor
or yarn release --release-as 1.1.0
,可以合并 --prerelease
以此方便发布实验性特性 Prevent Git Hooks:yarn release --no-verify
资源参考