軟技能提升:轉(zhuǎn)轉(zhuǎn)中后臺規(guī)范落地實(shí)踐

1. 背景
中臺覆蓋了多線業(yè)務(wù),自然對應(yīng)的不少后臺系統(tǒng),考慮日后到項(xiàng)目應(yīng)用,滿足業(yè)務(wù)的快速迭代,無論是技術(shù)版本升級、敏捷開發(fā)、可復(fù)用性和可維護(hù)性等。
我們需要針對當(dāng)下的痛點(diǎn),切合定一些強(qiáng)制規(guī)范和推薦規(guī)范。
1.1 痛點(diǎn)
新舊項(xiàng)目差異比較大,升級比較費(fèi)勁 老項(xiàng)目文檔不全 or 沒有 組件復(fù)用性不高 依賴同類功能的第三方庫,五花八門,沒有統(tǒng)一 切換項(xiàng)目開發(fā)時(shí),代碼校驗(yàn)規(guī)范不統(tǒng)一 沒有實(shí)際文檔,不便于新人培訓(xùn)等
1.2 項(xiàng)目相關(guān)規(guī)范
主要分為兩大模塊:強(qiáng)制規(guī)范和推薦規(guī)范,大致如下圖。

2. 如何落地?
2.1 技術(shù)方案
開發(fā)前,我們在技術(shù)選型和技術(shù)設(shè)計(jì)時(shí)通常會有調(diào)研某類技術(shù)或者項(xiàng)目設(shè)計(jì)方案,但我們通常選擇完后,沒有的文檔的輸出,以至于出現(xiàn)重復(fù)調(diào)研或“時(shí)間久了,忘記了”這種現(xiàn)象。所以,為了避免類似事情的發(fā)生,我們需要一定的文檔積累,但這些文檔至少需要包含什么內(nèi)容呢,這就需要我們協(xié)定下一定的規(guī)范。
2.1.1 技術(shù)選型規(guī)范文檔
#?XX?技術(shù)方案調(diào)研/選擇
##?背景
簡述下,技術(shù)調(diào)研/選擇背景(應(yīng)用場景),技術(shù)原理,目的是什么(為了解決 XX 問題)?
##?業(yè)界主流技術(shù)方案列舉
-?典型方案及?demo?實(shí)踐
-?對比其優(yōu)缺點(diǎn)
-?是否需要做方案優(yōu)點(diǎn)整合?
##?在實(shí)踐?Demo?中遇到的典型問題
-?闡述:問題?&&?原因?&&?解決方案
##?最終選擇該方案的亮點(diǎn)
-?闡述目前方案的較業(yè)界的優(yōu)點(diǎn),或者說優(yōu)化了某個(gè)缺點(diǎn)
-?可以從復(fù)用性,功能/兼容性等角度
##?可能存在的問題
-?預(yù)估存在的風(fēng)險(xiǎn)(后期的優(yōu)化規(guī)劃)
##?方案評審
-?若項(xiàng)目較大或較無把握,可以開一個(gè)方案評審會議
2.1.2 技術(shù)設(shè)計(jì)文檔規(guī)范
#?技術(shù)方案設(shè)計(jì)
>?根據(jù)具體的項(xiàng)目復(fù)雜度,進(jìn)行項(xiàng)目合理的技術(shù)設(shè)計(jì)。(此設(shè)計(jì)緯度,僅限前端)
???????注意:
1.?技術(shù)設(shè)計(jì)盡可能的基于目前公共資源,如果發(fā)現(xiàn)有設(shè)計(jì)不合理的地方,可以反饋公共支撐組優(yōu)化
2.?如果公共資源沒有的方案,盡可能的抽取出可公用的部分,返哺給公共組。
##?概要設(shè)計(jì)
###?架構(gòu)圖
目的:加深對整體的結(jié)構(gòu)足夠了解(可以向 pm、qa 和 rd 咨詢了解)
###?項(xiàng)目基礎(chǔ)結(jié)構(gòu)圖
目的:對項(xiàng)目的目錄/功能結(jié)構(gòu)加深理解
###?流程圖
流程圖是面向過程的,用于描述一個(gè)算法或者業(yè)務(wù)的過程。
目的:明確業(yè)務(wù)范圍,明確我們到底要做什么,不做什么,幫助識別邊界。
##?詳細(xì)設(shè)計(jì)
###?時(shí)序圖(交互圖)
目的:根據(jù)不同的視角看問題,可以從用戶的角度,切身思考???會遇到的問題,從而優(yōu)化用戶體驗(yàn)。
###?開發(fā)&測試用例-思維導(dǎo)圖
目的:梳理需求文檔,細(xì)化文案、設(shè)計(jì)和交互功能,每個(gè) case,防止文檔遺漏。
2.2 UI 規(guī)范
目前,我們整體的布局和大多數(shù)的組件風(fēng)格沿用的是 Ant Design,也會根據(jù)自身的業(yè)務(wù)特點(diǎn),與 PM 和 UI 設(shè)計(jì)配合,制定屬于我們的 UI 規(guī)范(主要圍繞三個(gè)維度:組件規(guī)范、頁面規(guī)范和組件使用規(guī)范),具體如表。
| 規(guī)范內(nèi)容 | 落地方法 |
|---|---|
| 組件規(guī)范 | 組件庫 |
| 頁面規(guī)范(包括色調(diào)、間距、頁面布局等) | 腳手架模板 |
| 組件使用規(guī)范 (比如某個(gè)地方應(yīng)該使用哪個(gè)組件;表格是否應(yīng)該支持列寬度拖動等) | 文檔及分享 |
2.3 項(xiàng)目中的規(guī)范
2.3.1 README 規(guī)范
README 文檔在項(xiàng)目中,相當(dāng)于項(xiàng)目的門面,好的 README 可以讓 下一任維護(hù)者一目了然。主要框架如下:
#?項(xiàng)目名
##?簡介(Introduction)
這里可以把項(xiàng)目背景簡單介紹下,可以把項(xiàng)目的目標(biāo)以及后面規(guī)劃的寫下。(可以咨詢相關(guān) pm)
##?方案選擇(Scheme)
包含內(nèi)容:方案設(shè)計(jì)選擇,可以寫調(diào)研的方案參考,優(yōu)缺點(diǎn),調(diào)研實(shí)踐 demo,以及最終選擇的原因等。
其他:
-?這部分過復(fù)雜,可以單獨(dú),對應(yīng)的項(xiàng)目目錄中,然后這里此?readme,標(biāo)注引導(dǎo)
-?可參考規(guī)范`【技術(shù)方案選擇文檔編寫規(guī)范】`
##?項(xiàng)目設(shè)計(jì)結(jié)構(gòu)(Structure)
包含內(nèi)容:最終的方案設(shè)計(jì),目錄 or 功能結(jié)構(gòu),這部分以圖表(流程圖或者思維導(dǎo)圖等)的形式展示,必要的主流程圖,細(xì)節(jié)交互可以補(bǔ)上對應(yīng)的測試用例等。
其他:
-?這部分過復(fù)雜,可以單獨(dú),對應(yīng)的項(xiàng)目目錄中,然后這里此?readme,標(biāo)注引導(dǎo)
-?可參考規(guī)范`【技術(shù)方案設(shè)計(jì)文檔編寫規(guī)范】`
##?使用(Usage)
#?安裝依賴(如果生成初始化項(xiàng)目時(shí)已經(jīng)安裝完畢,無需安裝)
npm?install
#?開發(fā)模式?localhost:8000
npm?run?dev
#?構(gòu)建模式
npm?run?build
#?構(gòu)建模式?+?分析報(bào)告
npm?run?analyz
#?語法校驗(yàn)
npm?run?lint
#?自動修復(fù)
npm?run?fix
#?按規(guī)范?git?commit?并自動生成?changelog
npm?run?cz
##?開發(fā)(Development)
具體開發(fā)注意事項(xiàng),使用的工具包,功能特征等等
###?頁面配置
-?頁面配置?1
-?頁面配置?2
###?頁面對應(yīng)地址
|?頁面??|?功能???|?地址????????????????|
|?-----?|?------?|?-------------------?|
|?home??|?首頁???|?https://xxxxx/home??|
|?about?|?詳情頁?|?https://xxxxx/about?|
##?API(Reference)
1.?api?1
2.?api?2
##?FAQ(常見問題解答)
1.?常見問題?1
2.?常見問題?2
##?附錄(Appendix)
-?[ChangeLog](?"ChangeLog")
-?[其他文檔](?"其他文檔")
2.3.2 目錄規(guī)范
目錄清晰,能夠讓開發(fā)者清楚的知道,什么地方,該做什么事,也便于維護(hù)者的對代碼的良好閱讀。
項(xiàng)目目錄
├──?CHANGELOG.md??????????????????//?[生成]?更新日志
├──?README.md?????????????????????//?[必選]?導(dǎo)讀
├──?config????????????????????????//?[可選]?配置目錄
│???├──?config.js?????????????????//?[生成]?基本配置
│???└──?router.config.js??????????//?[必填]?路由
├──?dist??????????????????????????//?[生成]?打包目錄
├──?docs??????????????????????????//?[可選]?文檔
├──?mock??????????????????????????//?[可選]?mock?數(shù)據(jù)
│???└──?sample.js?????????????????//?[可選]?demo
├──?package.json??????????????????//?[必選]?大家都懂
├──?public????????????????????????//?[必選]?不會被webpack編譯的資源
└──?src???????????????????????????//?[必選]?開發(fā)目錄
????├──?app.js????????????????????//?[必選]?運(yùn)行時(shí)配置文件
????├──?assets????????????????????//?[可選]?公共資源(被項(xiàng)目引用的經(jīng)過webpack處理的資源)
????├──?components????????????????//?[必選]?業(yè)務(wù)組件必須寫在這里
????├──?global.jsx????????????????//?[必選]?全局執(zhí)行入口
????├──?global.less???????????????//?[必選]?需要重置的樣式或者全局樣式引用
????├──?layouts???????????????????//?[可選]?基本的布局封裝
????├──?models????????????????????//?[可選]?對異步數(shù)據(jù)處理
????├──?pages?????????????????????//?[必選]?頁面組件,不允許有其他類型組件混入
????├──?services??????????????????//?[必選]?業(yè)務(wù)接口封裝
????└──?utils?????????????????????//?[可選]?工具庫(用于一些函數(shù)方法之類的庫)
├──?...
components、pages、services、models 具體職能劃分和文件格式
?? 注意:以 mock 中的 sample、pages 中的 sample、services 中的 sample、models 中的 sample 為例,名字需要一一對應(yīng)。
├──?mock??????????????????????????//?[可選]?mock?數(shù)據(jù)
│???└──?sample.js?????????????????//?[可選]?demo,文件名小寫
└──?src???????????????????????????//?[必選]?開發(fā)目錄
????├──?components????????????????//?[必選]?可公共業(yè)務(wù)組件必須寫在這里
????│???└──?CustomizeForm?????????//?[可選]?demo,文件名大寫駝峰
????│???│???└──?MoneyInput.jsx????//?[可選]?demo,組件名大寫駝峰
????│???│???└──?VideoUpload.jsx???//?[可選]?demo,組件名大寫駝峰
????├──?models????????????????????//?[可選]?對異步數(shù)據(jù)處理
????│???└──?sample.js?????????????//?[可選]?demo,文件名小寫
????├──?pages?????????????????????//?[必選]?頁面組件,不允許有其他類型組件混入
????│???└──?sample????????????????//?[可選]?demo,文件名小寫
????│???│???└──?components????????//?[可選]?頁面?zhèn)€性組件
????│???│???│???└──?DemoInput.jsx?//?[可選]?demo,頁面?zhèn)€性組件名大寫駝峰
????│???│???└──?index.jsx?????????//?[可選]?demo,文件名小寫,主入口都統(tǒng)一用index.jsx
????├──?services??????????????????//?[必選]?業(yè)務(wù)接口封裝
????│???└──?sample.js?????????????//?[可選]?demo,文件名小寫
├──?...
2.3.3 代碼規(guī)范
目前中后臺系統(tǒng),主要用的是 umi3 + antd4,基于此基礎(chǔ),主要針對 react 做一些規(guī)范。
2.3.4 基礎(chǔ)規(guī)范
ESLint 規(guī)范
ESLint 屬于一種 QA 工具,是一個(gè) ECMAScript/JavaScript 語法規(guī)則和代碼風(fēng)格的檢查工具,可以用來保證寫出語法正確、風(fēng)格統(tǒng)一的代碼。ESLint 旨在完全可配置,它的目標(biāo)是提供一個(gè)插件化的 javascript 代碼檢測工具。轉(zhuǎn)轉(zhuǎn)的 ESlint 配置基于 Standard 規(guī)則的基礎(chǔ)上做了特定的修改。
rules:?{
????//?末尾不加分號,只有在有可能語法錯誤時(shí)才會加分號
????semi:?0,
????//?箭頭函數(shù)需要有括號?(a)?=>?{}
????"arrow-parens":?0,
????//?兩個(gè)空格縮進(jìn),?switch?語句中的?case?為?1?個(gè)空格
????indent:?[
????????"error",
????????2,
????????{
????????SwitchCase:?1
????????}
????],
????//?關(guān)閉不允許回調(diào)未定義的變量
????"standard/no-callback-literal":?0,
????//?關(guān)閉副作用的?new
????"no-new":?"off",
????//?關(guān)閉每行最大長度小于?80
????"max-len":?0,
????//?函數(shù)括號前面不加空格
????"space-before-function-paren":?["error",?"never"],
????//?關(guān)閉要求?require()?出現(xiàn)在頂層模塊作用域中
????"global-require":?0,
????//?關(guān)閉關(guān)閉類方法中必須使用this
????"class-methods-use-this":?0,
????//?關(guān)閉禁止對原生對象或只讀的全局對象進(jìn)行賦值
????"no-global-assign":?0,
????//?關(guān)閉禁止對關(guān)系運(yùn)算符的左操作數(shù)使用否定操作符
????"no-unsafe-negation":?0,
????//?關(guān)閉禁止使用?console
????"no-console":?0,
????//?關(guān)閉禁止末尾空行
????"eol-last":?0,
????//?關(guān)閉強(qiáng)制在注釋中?//?或?/*?使用一致的空格
????"spaced-comment":?0,
????//?關(guān)閉禁止對?function?的參數(shù)進(jìn)行重新賦值
????"no-param-reassign":?0,
????//?強(qiáng)制使用一致的換行符風(fēng)格?(linebreak-style)
????"linebreak-style":?["error",?"unix"],
????//?關(guān)閉全等?===?校驗(yàn)
????"eqeqeq":?"off",
????//?禁止使用拖尾逗號(即末尾不加逗號)
????"comma-dangle":?["error",?"never"],
????//?關(guān)閉強(qiáng)制使用駱駝拼寫法命名約定
????"camelcase":?0
}
ignore 規(guī)范
gitignore:主要是在 git 提交的時(shí)候忽略掉某些目錄或者文件。
eslintignore:eslint 校驗(yàn)執(zhí)行時(shí),忽略某些文件。
prettierignore:不使用 prettier 格式化的文件填寫在項(xiàng)目的.prettierignore 文件中。
#?gitignore?規(guī)范
#?dependencies
**/node_modules
#?roadhog-api-doc?ignore
/src/utils/request-temp.js
_roadhog-api-doc
#?production
/dist
/.vscode
#?misc
.DS_Store
npm-debug.log*
yarn-error.log
/coverage
.idea
*bak
.vscode
#?visual?studio?code
.history
*.log
functions/*
.temp/**
#?umi
.umi
.umi-production
#?screenshot
screenshot
.firebase
.eslintcache
build
#?--------------------------------------------------------
#?eslintignore?規(guī)范
bash
/lambda/
/scripts
/config
.history
node-build.js
#?--------------------------------------------------------
#?prettierignore?規(guī)范
**/*.svg
package.json
.umi
.umi-production
/dist
.dockerignore
.DS_Store
.eslintignore
*.png
*.toml
docker
.editorconfig
Dockerfile*
.gitignore
.prettierignore
LICENSE
.eslintcache
*.lock
yarn-error.log
.history
.prettierrc
prettier 規(guī)范
Prettier 是近期比較火的代碼美化工具,其中文意思是“漂亮的、機(jī)靈的”,它能夠解析代碼,使用你自己設(shè)定的規(guī)則來重新打印出格式規(guī)范的代碼。
{
????//?在ES5中有效的結(jié)尾逗號(對象,數(shù)組等)
????trailingComma:?'es5',
????//?不使用縮進(jìn)符,而使用空格
????useTabs:?false,
????//?tab?用兩個(gè)空格代替
????tabWidth:?2,
????//?僅在語法可能出現(xiàn)錯誤的時(shí)候才會添加分號
????semi:?false,
????//?使用單引號
????singleQuote:?true,
????//?一行最多?100?字符
????printWidth:?100,
????//?對象的?key?僅在必要時(shí)用引號
????quoteProps:?'as-needed',
????//?jsx?不使用單引號,而使用雙引號
????jsxSingleQuote:?false,
????//?大括號內(nèi)的首尾需要空格
????bracketSpacing:?true,
????//?jsx?標(biāo)簽的反尖括號需要換行
????jsxBracketSameLine:?false,
????//?箭頭函數(shù),只有一個(gè)參數(shù)的時(shí)候,也需要括號
????arrowParens:?'always',
????//?每個(gè)文件格式化的范圍是文件的全部內(nèi)容
????rangeStart:?0,
????rangeEnd:?Infinity,
????//?不需要寫文件開頭的?@prettier
????requirePragma:?false,
????//?不需要自動在文件開頭插入?@prettier
????insertPragma:?false,
????//?使用默認(rèn)的折行標(biāo)準(zhǔn)
????proseWrap:?'preserve',
????//?根據(jù)顯示樣式?jīng)Q定?html?要不要折行
????htmlWhitespaceSensitivity:?'css',
????//?換行符使用?lf
????endOfLine:?'lf'
}
stylelint 規(guī)范
stylelint 有一百多條的校驗(yàn)規(guī)則,并且還在逐步增加...盡管如此,但是他們都是默認(rèn)關(guān)閉的我們是基于 stylelint-config-standard。
??rules:?{
??????'no-descending-specificity':?null,?????????????????????????????????????//?禁止低優(yōu)先級的選擇器出現(xiàn)在高優(yōu)先級的選擇器之后,https://github.com/stylelint/stylelint/issues/4114
??????'function-calc-no-invalid':?null,??????????????????????????????????????//?非法calc方法
??????'font-family-no-missing-generic-family-keyword':?null,?????????????????//?顏色16進(jìn)制指定為長符號,iconfont
??????'plugin/declaration-block-no-ignored-properties':?true,
??????'unit-no-unknown':?[true,?{?ignoreUnits:?['rpx']?}]
??}
??//?官方文檔來源
??[@umijs/fabric?stylelint](https://github.com/umijs/fabric/blob/master/src/stylelint.ts?"@umijs/fabric?stylelint")
??[stylelint?更多中文解釋](http://stylelint.cn/user-guide/rules/?"stylelint?更多中文解釋")
??[stylelint-config-standard](https://github.com/stylelint/stylelint-config-standard?"stylelint-config-standard")
??[stylelint-config-css-modules](https://github.com/css-modules/css-modules?"stylelint-config-css-modules")
??[stylelint-config-rational-order](https://github.com/constverum/stylelint-config-rational-order?"stylelint-config-rational-order")
??[stylelint-config-prettier](https://github.com/prettier/stylelint-config-prettier#readme?"stylelint-config-prettier")
還有其他,包括編輯規(guī)范都是基于公共規(guī)范定,等等,這里就不一一列舉了。

3. 為什么這么做?
當(dāng)然,規(guī)范化,并不是說定好后就能立馬徹底解決以上所有痛點(diǎn),而是優(yōu)先針對增量的項(xiàng)目進(jìn)行規(guī)范,逐步的積累我們的公共基礎(chǔ)能力,提高可復(fù)用和可維護(hù)性。
等我們對老項(xiàng)目重構(gòu)的時(shí)候,按照規(guī)范開發(fā),是不是以后迭代開發(fā)和維護(hù)就會更輕松了呢?
規(guī)范化,不僅僅是規(guī)范項(xiàng)目,也同時(shí)規(guī)范我們的良好習(xí)慣。
努力完善吧,老鐵們~加油!!!
本月文章預(yù)告
預(yù)告下,接下來我們會陸續(xù)發(fā)布轉(zhuǎn)轉(zhuǎn)在微前端、Umi、組件庫等基礎(chǔ)架構(gòu)和中臺技術(shù)相關(guān)的實(shí)踐與思考,歡迎大家關(guān)注,期望與大家多多交流
