<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          前端中小團(tuán)隊(duì) GitLab 最佳實(shí)踐(文末送書)

          共 10142字,需瀏覽 21分鐘

           ·

          2021-03-11 18:45

          最近團(tuán)隊(duì)代碼庫從Gerrit遷移到了Gitlab,為了讓前端團(tuán)隊(duì)日常開發(fā)工作有條不紊高效運(yùn)轉(zhuǎn),開發(fā)歷史可追溯,我也查閱和學(xué)習(xí)了不少資料。參考業(yè)界主流的Git工作流,結(jié)合公司業(yè)務(wù)特質(zhì),我也梳理了一套適合自己團(tuán)隊(duì)的Git工作流,在這里做下分享。

          分支管理

          首先要說的是分支管理,分支管理是git工作流的基礎(chǔ),好的分支設(shè)計(jì)有助于規(guī)范開發(fā)流程,也是CI/CD的基礎(chǔ)。

          分支策略

          業(yè)界主流的git工作流,一般會(huì)分為developreleasemasterhotfix/xxxfeature/xxx等分支。各個(gè)分支各司其職,貫穿了整個(gè)開發(fā),測(cè)試,部署流程。我這里也基于主流的分支策略做了一些定制,下面用一張表格簡(jiǎn)單概括下:

          分支名分支定位描述權(quán)限控制
          develop開發(fā)分支不可以在develop分支push代碼,應(yīng)新建feature/xxx進(jìn)行需求開發(fā)。迭代功能開發(fā)完成后的代碼都會(huì)merge到develop分支。Develper不可直接push,可發(fā)起merge request
          feature/xxx特性分支針對(duì)每一項(xiàng)需求,新建feature分支,如feature/user_login,用于開發(fā)用戶登錄功能。Develper可直接push
          release提測(cè)分支由develop分支合入release分支。ps: 應(yīng)配置此分支觸發(fā)CI/CD,部署至測(cè)試環(huán)境。Maintainer可發(fā)起merge request
          bug/xxx缺陷分支提測(cè)后發(fā)現(xiàn)的bug,應(yīng)基于develop分支創(chuàng)建bug/xxx分支修復(fù)缺陷,修改完畢后應(yīng)合入develop分支等待回歸測(cè)試。
          master發(fā)布分支master應(yīng)處于隨時(shí)可發(fā)布的狀態(tài),用于對(duì)外發(fā)布正式版本。ps: 應(yīng)配置此分支觸發(fā)CI/CD,部署至生產(chǎn)環(huán)境。Maintainer可發(fā)起merge request
          hotfix/xxx熱修復(fù)分支處理線上最新版本出現(xiàn)的bugDevelper可直接push
          fix/xxx舊版本修復(fù)分支處理線上舊版本的bugDevelper可直接push

          一般來說,developreleasemaster分支是必備的。而feature/xxxbug/xxxhotfix/xxxfix/xxx等分支純屬一種語義化的分支命名,如果要簡(jiǎn)單粗暴一點(diǎn),這些分支可以不分類,都命名為issue/issue號(hào),比如issue/1,但是要在issue中說明具體問題和待辦事項(xiàng),保證開發(fā)工作可追溯。

          保護(hù)分支

          利用Protected Branches,我們可以防止開發(fā)人員錯(cuò)誤地將代碼push到某些分支。對(duì)于普通開發(fā)人員,我們僅對(duì)develop分支提供merge權(quán)限。

          保護(hù)分支

          具體操作案例請(qǐng)前往下面的實(shí)戰(zhàn)案例一節(jié)查看。

          issue驅(qū)動(dòng)工作

          我們團(tuán)隊(duì)采用的敏捷開發(fā)協(xié)作平臺(tái)是騰訊的TAPD[1],日常迭代需求,缺陷等都會(huì)在TAPD上記錄。為了讓Gitlab代碼庫能與迭代日常事務(wù)關(guān)聯(lián)上,我決定用Gitlab issues來做記錄,方便追溯問題。

          里程碑

          里程碑Milestone可以認(rèn)為是一個(gè)階段性的目標(biāo),比如是一輪迭代計(jì)劃。里程碑可以設(shè)定時(shí)間范圍,用來約束和提醒開發(fā)人員。

          milestones

          里程碑可以拆解為N個(gè)issue,新建issue時(shí)可以關(guān)聯(lián)里程碑。比如這輪迭代一共5個(gè)需求,那么就可以新建5個(gè)issue。在約定的時(shí)間范圍內(nèi),如果一個(gè)里程碑關(guān)聯(lián)的所有issueClosed掉了,就意味著目標(biāo)順利達(dá)成。

          創(chuàng)建issue

          標(biāo)簽

          Gitlab提供了label來標(biāo)識(shí)和分類issue,我覺得這是一個(gè)非常好的功能。我這里列舉了幾種label,用來標(biāo)識(shí)issue分類緊急程度

          標(biāo)簽管理

          issue分類

          所有的開發(fā)工作應(yīng)該通過issue記錄,包括但不限于需求缺陷開發(fā)自測(cè)試用戶體驗(yàn)等范疇。

          需求&缺陷

          這里大概又分為兩種情況,一種是TAPD記錄在案的需求和缺陷,另一種是與產(chǎn)品或測(cè)試人員口頭溝通時(shí)傳達(dá)的簡(jiǎn)單需求或缺陷(小公司會(huì)有這種情況...)。

          對(duì)于TAPD記錄的需求和缺陷,創(chuàng)建issue時(shí)應(yīng)附上鏈接,方便查閱(上文中已有提到)。

          對(duì)于口頭溝通的需求和缺陷,我定了個(gè)規(guī)則,要求提出人本人在Gitlab上創(chuàng)建issue,并將需求或缺陷簡(jiǎn)單描述清楚,否則口頭溝通的開發(fā)工作我不接(也是為了避免事后扯皮)。

          ps:其實(shí)要求產(chǎn)品或者測(cè)試提issue,還不如上Tapd記錄。我定這么個(gè)規(guī)則,其實(shí)就是借Gitlab找個(gè)說辭,杜絕口頭類需求或缺陷,哈哈。

          開發(fā)自測(cè)試

          開發(fā)者自己發(fā)現(xiàn)了系統(tǒng)缺陷或問題,此時(shí)應(yīng)該通過issue記錄問題,并創(chuàng)建相應(yīng)分支修改代碼。

          自測(cè)試issue

          實(shí)戰(zhàn)案例

          我前面也說了,我的原則是issue驅(qū)動(dòng)開發(fā)工作。

          下面用幾個(gè)例子來簡(jiǎn)單說明基本的開發(fā)流程。小公司里整個(gè)流程比較簡(jiǎn)單,沒有復(fù)雜的集成測(cè)試,多輪驗(yàn)收測(cè)試,灰度測(cè)試等。我甚至連單元測(cè)試都沒做(捂臉...)。

          公共庫和公共組件其實(shí)是很有必要做單元測(cè)試的,這里立個(gè)flag,后面一定補(bǔ)上單元測(cè)試。

          需求開發(fā)

          feature/1,一個(gè)特性分支,對(duì)應(yīng)issue 1

          創(chuàng)建需求

          正常的需求當(dāng)然來源于產(chǎn)品經(jīng)理等需求提出方,由于是通過示例說明,這里我自己在TAPD上模擬著寫一個(gè)需求。

          TAPD創(chuàng)建需求

          創(chuàng)建issue

          創(chuàng)建Gitlab issue,鏈接到TAPD中的相關(guān)需求。

          創(chuàng)建issue
          一個(gè)issue

          創(chuàng)建分支&功能開發(fā)

          基于develop分支創(chuàng)建feature分支進(jìn)行功能開發(fā)(要保證本地git倉庫當(dāng)前處于develop分支,且與遠(yuǎn)程倉庫develop分支同步)。

          git checkout -b feature/1

          或者直接以遠(yuǎn)程倉庫的develop分支為基礎(chǔ)創(chuàng)建分支。

          git checkout -b feature/1 origin/develop

          ps:我這里用的feature/1作為分支名,其實(shí)這里的1是用的issue號(hào),并沒有用諸如feature/login_verify之類的名字,是因?yàn)槲矣X得用issue號(hào)可以更方便地找到對(duì)應(yīng)的issue,更容易追蹤代碼。

          接著我們開始開發(fā)新功能......

          快樂地?cái)]代碼

          commit & push

          完成功能開發(fā)后,我們需要提交代碼并同步到遠(yuǎn)程倉庫。

          PS D:\projects\gitlab\project_xxx> git add .
          PS D:\projects\gitlab\project_xxx> git cz
          [email protected], [email protected]

          ? Select the type of change that you're committing: feat: A new feature
          ? What is the scope of this change (e.g. component or file name): (press enter to skip)
          ? Write a short, imperative tense description of the change (max 94 chars):
          (9) 登錄校驗(yàn)功能
          ? Provide a longer description of the change: (press enter to skip)

          ? Are there any breaking changes? No
          ? Does this change affect any open issues? Yes
          ? If issues are closed, the commit requires a body. Please enter a longer description of the commit itself:
          -
          ? Add issue references (e.g. "fix #123", "re #123".):
          fix #1

          git push origin HEAD

          git cz是利用了commitizen來替代git commit。詳情請(qǐng)點(diǎn)擊前端自動(dòng)化部署的深度實(shí)踐深入了解。

          fix #1用于關(guān)閉issue 1

          git push origin HEAD則代表推送到遠(yuǎn)程倉庫同名分支。

          創(chuàng)建Merge Request

          開發(fā)人員發(fā)起Merge Request,請(qǐng)求將自己開發(fā)的功能特性合入develop分支。

          創(chuàng)建Merge Request

          接著Maintainer需要Review代碼,確認(rèn)無誤后同意Merge。然后這部分代碼就在遠(yuǎn)程Git倉庫入庫了,其他開發(fā)同學(xué)拉取develop分支就能看到了。

          版本提測(cè)

          issue/2,處理更新日志,版本號(hào)等內(nèi)容,對(duì)應(yīng)issue 2

          每個(gè)團(tuán)隊(duì)的開發(fā)節(jié)奏都不同,有的團(tuán)隊(duì)會(huì)每日持續(xù)集成發(fā)版本提測(cè),有的可能兩天一次,這個(gè)就不深入討論了......

          那么當(dāng)我們準(zhǔn)備提測(cè)時(shí),應(yīng)該怎么做呢?

          通過上節(jié)的了解,我們已經(jīng)知道,迭代內(nèi)的功能需求都會(huì)通過feature/xxx分支合入到develop分支。

          提測(cè)前,一般來說,還是要更新下CHANGELOG.mdpackage.json的版本號(hào),可以由Maintainer或其他負(fù)責(zé)該項(xiàng)事務(wù)的同學(xué)執(zhí)行。

          主要是執(zhí)行npm version major/minor/patch -m 'something done',具體操作可以參考前端自動(dòng)化部署的深度實(shí)踐一文。

          git checkout -b issue/2 origin/develop
          npm version minor -m '迭代1第一次提測(cè)'
          git push origin HEAD
          然后發(fā)起merge request合入develop分支

          此時(shí),應(yīng)以最新的develop分支代碼在開發(fā)環(huán)境跑一遍功能,保證版本自測(cè)通過。

          提測(cè)時(shí),由Maintainer發(fā)起Merge Request,將develop分支代碼合入release分支,此時(shí)自動(dòng)觸發(fā)Gitlab CI/CD,自動(dòng)構(gòu)建并發(fā)布至測(cè)試環(huán)境

          版本提測(cè)后,各責(zé)任人應(yīng)在TAPD上將相關(guān)需求和缺陷的狀態(tài)變更為**“測(cè)試中”**。

          修復(fù)測(cè)試環(huán)境bug

          bug/3,一個(gè)bug分支,對(duì)應(yīng)issue 3

          這里說的是在迭代周期內(nèi)由測(cè)試工程師發(fā)現(xiàn)的測(cè)試環(huán)境中的系統(tǒng)bug,這些bug會(huì)被記錄在敏捷開發(fā)協(xié)作平臺(tái)TAPD上。修復(fù)測(cè)試環(huán)境bug的步驟與開發(fā)需求類似,這里簡(jiǎn)單說下步驟:

          1. 在Gitlab上創(chuàng)建issue

            創(chuàng)建issue,并附上TAPD上的缺陷鏈接,方便追溯

          2. 創(chuàng)建分支&修復(fù)缺陷

            基于develop分支創(chuàng)建分支:

            // 3是issue號(hào)
            git checkout -b bug/3 origin/develop

            接著改代碼......

          3. commit & push

            PS D:\projects\gitlab\project_xxx> git cz
            [email protected], [email protected]

            ? Select the type of change that you're committing: fix: A bug fix
            ? What is the scope of this change (e.g. component or file name): (press enter to skip)
            ? Write a short, imperative tense description of the change (max 95 chars):
            (11) 修復(fù)一個(gè)測(cè)試環(huán)境bug
            ? Provide a longer description of the change: (press enter to skip)

            ? Are there any breaking changes? No
            ? Does this change affect any open issues? Yes
            ? If issues are closed, the commit requires a body. Please enter a longer description of the commit itself:
            -
            ? Add issue references (e.g. "fix #123", "re #123".):
            fix #3

            git push origin HEAD
          4. 發(fā)起Merge Request

            開發(fā)人員發(fā)起Merge Request,請(qǐng)求將自己修復(fù)缺陷引入的代碼合入develop分支。

            然后Maintainer需要Review代碼,同意本次Merge Request

          5. 等待回歸測(cè)試

            bug將在下一次CI/CD后,進(jìn)入回歸測(cè)試流程。

          6. 級(jí)別高的測(cè)試環(huán)境Bug

            如果是級(jí)別很高的bug,比如影響了系統(tǒng)運(yùn)行,導(dǎo)致測(cè)試人員無法正常測(cè)試的,應(yīng)以release分支為基礎(chǔ)創(chuàng)建bug分支,修改完畢后合入release分支,再發(fā)起cherry pick合入develop分支。

          發(fā)布至生產(chǎn)環(huán)境

          經(jīng)過幾輪持續(xù)集成和回歸測(cè)試后,一個(gè)迭代版本也慢慢趨于穩(wěn)定,此時(shí)也迎來了激動(dòng)人心的上線時(shí)間。我們要做的就是把通過了測(cè)試的release分支合入master分支。

          release合入master

          這一步相對(duì)簡(jiǎn)單,但是要特別注意權(quán)限控制(防止生產(chǎn)環(huán)境事故),具體權(quán)限控制可以回頭看第一章節(jié)分支管理

          release分支類似,master分支自動(dòng)觸發(fā)Gitlab CI/CD,自動(dòng)構(gòu)建并發(fā)布至生產(chǎn)環(huán)境

          線上回滾

          revert/4,一個(gè)回滾分支,對(duì)應(yīng)issue 4

          代碼升級(jí)到線上,但是發(fā)現(xiàn)報(bào)錯(cuò),系統(tǒng)無法正常運(yùn)行。此時(shí)如果不能及時(shí)排查出問題,那么只能先進(jìn)行版本回退操作。

          先說說慣性思維下,我的版本回退做法。

          首先還是創(chuàng)建issue記錄下:

          創(chuàng)建記錄回滾的issue

          基于master分支創(chuàng)建revert/4分支

          git checkout -b revert/4 origin/master

          假設(shè)當(dāng)前版本是1.1.0,我們想回退到上個(gè)版本1.0.3。那么我們需要先查看下1.0.3版本的信息。

          PS D:\tusi\projects\gitlab\projectname> git show 1.0.3
          commit 90c9170a499c2c5f8f8cf4e97fc49a91d714be50 (tag: 1.0.3, fix/1.0.2_has_bug)
          Author: tusi <[email protected]>
          Date: Thu Feb 20 13:29:31 2020 +0800

          fix:1.0.2

          diff --git a/README.md b/README.md
          index ac831d0..2ee623b 100644
          --- a/README.md
          +++ b/README.md
          @@ -10,6 +10,8 @@

          只想修改舊版本的bug,不改最新的master

          +1.0.2版本還是有個(gè)版本,再修復(fù)下
          +
          特性2提交

          特性3提交

          主要是取到1.0.3版本對(duì)應(yīng)的commit id,其值為90c9170a499c2c5f8f8cf4e97fc49a91d714be50

          接著,我們根據(jù)commit id進(jìn)行reset操作,再推送到遠(yuǎn)程同名分支。

          git reset --hard 90c9170a499c2c5f8f8cf4e97fc49a91d714be50
          git push origin HEAD

          接著發(fā)起Merge Requestrevert/4分支合入master分支。

          回滾分支合入master

          一般來說,這波操作沒什么問題,能解決常規(guī)的回滾問題。

          臨時(shí)變通

          由于master分支是保護(hù)分支,設(shè)置了不可push。如果不想通過merge的方式回滾,所以只能先臨時(shí)設(shè)置Maintainer擁有push權(quán)限,然后由Maintainer進(jìn)行回滾操作。

          git checkout master
          git pull
          git show 1.0.3
          git reset --hard 90c9170a499c2c5f8f8cf4e97fc49a91d714be50
          git push origin HEAD

          完事后,還需要記得把master設(shè)置為不可push

          Q: 為什么不讓Maintainer一直擁有masterpush權(quán)限?

          A: 主要還是為了防止出現(xiàn)生產(chǎn)環(huán)境事故,給予臨時(shí)性權(quán)限更穩(wěn)妥!

          git reset --hard存在什么問題?

          如題,git reset --hard確實(shí)是存在問題的。git reset --hard屬于霸道玩法,直接移動(dòng)HEAD指針,會(huì)丟棄之后的提交記錄,如果不慎誤操作了也別慌,還是可以通過查詢git reflog找到commitId搶救回來的;git reset后還存在一個(gè)隱性的問題,如果與舊的branch進(jìn)行merge操作時(shí),會(huì)把git reset回滾的代碼重新引入。那么怎么解決這些問題呢?

          一籌莫展

          別慌,這個(gè)時(shí)候你必須掏出git revert了。

          Q: git revert的優(yōu)勢(shì)在哪?

          A: 首先,git revert是通過一次新的commit來進(jìn)行回滾操作的,HEAD指針向前移動(dòng),這樣就不會(huì)丟失記錄;另外,git revert也不會(huì)引起merge舊分支時(shí)誤引入回滾的代碼。最重要的是,git revert在回滾的細(xì)節(jié)控制上更加優(yōu)秀,可解決部分回滾的需求。

          舉個(gè)栗子,本輪迭代團(tuán)隊(duì)共完成需求2項(xiàng),而上線后發(fā)現(xiàn)其中1項(xiàng)需求有致命性缺陷,需要回滾這個(gè)需求相關(guān)的代碼,同時(shí)要保留另一個(gè)需求的代碼。

          我太難了

          首先我們查看下日志,找下這兩個(gè)需求的commitId

          PS D:\tusi\projects\test\git_test> git log --oneline
          86252da (HEAD -> master, origin/master, origin/HEAD) 解決沖突
          e3cef4e (origin/release, release) Merge branch 'develop' into 'release'
          f247f38 (origin/develop, develop) 需求2
          89502c2 需求1

          我們利用git revert回滾需求1相關(guān)的代碼

          git revert -n 89502c2

          這時(shí)可能要解決沖突,解決完沖突后就可以push到遠(yuǎn)程master分支了。

          git add .
          git commit -m '回滾需求1的相關(guān)代碼,并解決沖突'
          git push origin master

          感覺還是菜菜的,如果大佬們有更優(yōu)雅的解決方案,求指導(dǎo)啊!

          修復(fù)線上bug

          hotfix/5,一個(gè)線上熱修復(fù)分支,對(duì)應(yīng)issue 5

          比如線上出現(xiàn)了系統(tǒng)無法登錄的bug,測(cè)試工程師也在TAPD提交了缺陷記錄。那么修復(fù)線上bug的步驟是什么呢?

          1. 創(chuàng)建issue,標(biāo)題可以從TAPD中的Bug單中copy過來,而描述就貼上Bug單的鏈接即可。

          2. 基于master分支創(chuàng)建分支hotfix/5

            git checkout -b hotfix/5 origin/master
          3. 擼代碼,修復(fù)此bug......

          4. 修復(fù)完此bug后,提交該分支代碼到遠(yuǎn)程倉庫同名分支

            git push origin HEAD
          5. 然后發(fā)起cherry pick合入到masterdevelop分支,并在master分支打上新的版本tag(假設(shè)當(dāng)前最大的tag1.0.0,那么新的版本tag應(yīng)為1.0.1)。

          修復(fù)線上舊版本bug

          fix/6,一個(gè)線上舊版本修復(fù)分支,對(duì)應(yīng)issue 6

          某些項(xiàng)目產(chǎn)品可能會(huì)有多個(gè)線上版本同時(shí)在運(yùn)行,那么不可避免要解決舊版本的bug。針對(duì)線上舊版本出現(xiàn)的bug,修復(fù)步驟與上節(jié)類似。

          1. 創(chuàng)建issue,描述清楚問題

          2. 假設(shè)當(dāng)前版本是1.0.0,而0.9.0版本出了一個(gè)bug,應(yīng)基于tag 0.9.0創(chuàng)建fix分支。

            git checkout -b fix/6 0.9.0
          3. 修復(fù)缺陷后,應(yīng)打上新的tag 0.9.1,并推送到遠(yuǎn)程。

            git tag 0.9.1
            git push origin tag 0.9.1
          4. 如果此bug也存在于最新的master分支,則需要git push origin HEAD提交該fix分支代碼到遠(yuǎn)程倉庫同名分支,然后發(fā)起cherry pick合入到master,此時(shí)很大可能存在沖突,需要解決沖突。

            cherry pick

          cherry pick

          在了解到cherry pick之前,我一直認(rèn)為只有git merge可以合并代碼,也好幾次遇到合入了不想要的代碼的問題。有了cherry pick,我們就可以合并單次提交記錄,解決git merge時(shí)合并太多不想要的內(nèi)容的煩惱,在解決bug時(shí)特別有用。

          git rebase

          經(jīng)過這段時(shí)間的使用,我發(fā)現(xiàn)使用git merge合并分支時(shí),會(huì)讓git logGraph圖看起來有點(diǎn)吃力。

          PS D:\tusi\projects\gitlab\projectname> git log --pretty --oneline --graph
          * 7f513b0 (HEAD -> develop) Merge branch 'issue/55' into 'release'
          |\
          | * 1c94437 (origin/issue/55, issue/55) fix: 【bug】XXX1
          | * c84edd6 Merge branch 'release' of host:project_repository into release
          | |\
          | |/
          |/|
          * | 115a26c Merge branch 'develop' into 'release'
          |\ \
          | * \ 60d7de6 Merge branch 'issue/30' into 'develop'
          | |\ \
          | | * | 27c59e8 (origin/issue/30, issue/30) fix: 【bug】XXX2
          | | | * ea17250 Merge branch 'release' of host:project_repository into release
          | | | |\
          | |_|_|/
          |/| | |
          * | | | 9fd704b Merge branch 'develop' into 'release'
          |\ \ \ \
          | |/ / /
          | * | | a774d26 Merge branch 'issue/30' into 'develop'
          | |\ \ \
          | | |/ /

          接著我就了解到了git rebase,變基,哈哈哈。由于對(duì)rebase了解不深,目前也不敢輕易改用rebase,畢竟rebase還是有很多隱藏的坑的,使用起來要慎重!在這里先挖個(gè)坑吧,后面搞懂了再填坑......

          注意事項(xiàng)

          1. 一般而言,自己發(fā)起的Merge Request必須由別的同事Review并同意合入,這樣更有利于發(fā)現(xiàn)代碼問題。
          2. 對(duì)了,TAPD還支持與Gitlab協(xié)同的。詳情見源碼關(guān)聯(lián)指引[2]

          結(jié)語

          實(shí)踐證明,這套Git工作流目前能覆蓋我項(xiàng)目開發(fā)過程中的絕大部分場(chǎng)景。不過要注意的是,適合自己的才是最好的,盲目采用別人的方案有時(shí)候是會(huì)水土不服的。

          以上所述純屬前端小微團(tuán)隊(duì)內(nèi)部的Gitlab實(shí)踐,必然存在著很多不足之處,如有錯(cuò)誤之處還請(qǐng)指正,歡迎交流。

          參考資料

          [1]

          TAPD: https://www.tapd.cn/

          [2]

          源碼關(guān)聯(lián)指引: https://www.tapd.cn/help/view#1120003271001001346



          最近上市的新書《前端函數(shù)式演進(jìn)》是一部寫給前端工程師的函數(shù)式編程實(shí)戰(zhàn)指南,由阿里本地生活企業(yè)訂餐前端負(fù)責(zé)人撰寫。


          作者結(jié)合自己在前端領(lǐng)域的大量工程實(shí)踐經(jīng)驗(yàn),首先從前端開發(fā)者的角度介紹了函數(shù)式編程在前端領(lǐng)域的演進(jìn),以及前端必備的函數(shù)式編程知識(shí);然后對(duì)React和RxJS等流行前端工具的函數(shù)式編程功能和思想進(jìn)行了深入剖析,既可以幫助讀者更好地理解和使用這些工具,又能給予讀者技術(shù)選型方面的建議。此外,書中提供了平臺(tái)級(jí)別的前端開發(fā)示例的多種實(shí)現(xiàn),方便讀者結(jié)合書中的理論進(jìn)行印證和思考。



          這本書還是挺不錯(cuò)的,推介一下 ,最后給本公眾號(hào)粉絲送出 12 個(gè)小禮物(在下大出血),包括 3 本前端函數(shù)式演進(jìn)。


          廢話少說,抽獎(jiǎng)在下面:



          瀏覽 74
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  丁香五月六月婷婷 | 美女高潮视频免费在线观看 | 91精品国产综合久久久久久 | 草草视频免费观看 | 精品久久中文娱乐网 |