通常開源項目正常的開發流程是:javascript
表面看起來沒有什麼毛病,可是要作一個規範的、多人協做的、可維護的開源項目,開發流程上仍是有很多細節的點須要咱們來打磨。html
那在多人協做的開發過程當中到底會碰到哪些沒法統一的行爲?咱們該如何解決這些問題?前端
這是一個老生常談的問題,語句結尾要不要分號?縮進是空格仍是tab?是2個仍是4個?java
目前業界比較統一的作法是使用eslintreact
做爲項目owner,建議全局安裝eslint
:git
npm install eslint -g
複製代碼
以後就能夠在本地的項目倉庫中,執行命令:github
eslint --init
複製代碼
能夠有三種選擇:npm
常規的前端項目建議選用Standard
規範(雖然不是真正的規範,可是屬於業內默認的規範吧),初始化以下:json
{
"devDependencies": {
"eslint": "^4.19.1",
"eslint-plugin-import": "^2.13.0",
"eslint-config-standard": "^11.0.0",
"eslint-plugin-standard": "^3.1.0",
"eslint-plugin-promise": "^3.8.0",
}
}
複製代碼
React項目建議選用Airbnb
規範,初始化後的package.json
以下:promise
{
"devDependencies": {
"eslint": "^4.19.1",
"eslint-config-airbnb": "^17.0.0",
"eslint-plugin-import": "^2.13.0",
"eslint-plugin-react": "^7.10.0",
"eslint-plugin-jsx-a11y": "^6.1.1"
}
}
複製代碼
若是須要單獨定義一些規則,能夠在根目錄下新建一個.eslintrc
文件,見具體配置。
若是須要忽略一些文件,能夠在根目錄下新建一個.eslintignore
文件,見具體配置。
最後在package.json
中加上命令
{
"scripts": {
"lint": "eslint --ext .jsx,.js ."
}
}
複製代碼
這樣項目成員只須要操做如下步驟
vscode
中安裝eslint
擴展(之後使用vscode
打開項目都會檢測項目中的.eslintrc
文件進行實時lint提示)cd project && npm install
若是是以前的老項目接入了eslint,同時加入了git hook來強制執行,會致使以前的錯誤沒修復完沒法提交,那有沒有辦法只檢測當前修改的文件呢?
目前社區比較成熟的方案是lint-staged
首先在項目中安裝lint-staged
和husky
husky是用來實現綁定git hooks的一個庫,後面會提到
npm install -D lint-staged husky
複製代碼
而後在項目中的package.json
中添加
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"*.js": ["eslint --fix", "git add"]
}
}
複製代碼
以上操做在咱們正常的開發流程中作了什麼呢?
在
git add .
以後,git commit
以前,會觸發precommit
鉤子,執行lint-staged
,而後lint-staged
會只檢查通過暫存區的文件,根據它的配置項執行命令。例如上面的配置,就是針對全部修改過的以
js
爲後綴的文件,依次執行eslint --fix
,git add
兩個命令,幫你自動修復掉eslint
的錯誤,再將修改添加到暫存區,而後一塊兒commit
到工做區。
eslint只是做爲代碼檢測的工具,並無規範開發時的行爲,那可不能夠在編輯器上進行規範呢?
主流方案是使用EditorConfig
首先在項目根目錄新建一個.editorconfig
文件,根據EditorConfig支持的大部分屬性自行定義
而後再給編輯器安裝EditorConfig
的插件,就可使用了,插件安裝可見官方下載
commit message
在實際開發的過程當中,其實你們對本身的修改內容並無很好的界定,也沒有統一的格式化,致使了不少時候咱們沒法根據commit message來快速定位修改內容。
changelog
其實一個項目新增功能,修復bug等信息都須要記錄下來,便於區別不一樣版本的新特性,而後手動維護記錄一般容易忘記,致使這一部分常常沒有持續的更新。
目前社區使用最廣的方案是Commitizen和conventional-changelog配合使用。
顧名思義
commitizen
就是用來規範commit message
conventional-changelog
能夠根據格式化的commit message
來自動生成CHANGLOG.md
有兩種開發方式:
全局安裝(牆裂推薦):
npm install commitizen -g
複製代碼
而後安裝commitizen
的adpater
,好比cz-conventional-changelog
(AngularJS的提交慣例)
npm install -g cz-conventional-changelog
複製代碼
而後你就可使用git cz
來替換git commit
命令來進行代碼提交了。
項目安裝:
讓你的項目讓別人更友好的接入commit規範,你不可能強制要求別人全局安裝一個工具,就只能在開發依賴裏添加
做爲項目owner,默認已經全局安裝了commitizen
,而後執行:
commitizen init cz-conventional-changelog --save-dev --save-exact
複製代碼
以上命令作了三件事:
在本地安裝cz-conventional-changelog
模塊
保存到package.json
的devDependencies
中
在package.json
的根層級添加了config.commitizen
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
}
複製代碼
爲了保證其餘貢獻者的倉庫中也能使用同一版本的commitizen
,最好在倉庫安裝開發依賴
npm install -D commitizen
複製代碼
而後在項目的package.json
中的scripts
里加上
{
"scripts": {
"cz": "git-cz"
}
}
複製代碼
這裏須要注意一點,若是你在
scripts
腳本中定義了{"commit": "git-cz"}
的話,precommit
鉤子會在真正commit以前執行兩次,見husky issue,因此自定義另一個名稱就行了。
而後項目contributors就能夠經過npm run cz
來愉快的提交格式化的commit message了。
仍是國際慣例,全局安裝
npm install -g conventional-changelog-cli
複製代碼
切換到項目目錄後,執行
conventional-changelog -p angular -i CHANGELOG.md -s -r 0
複製代碼
就能夠根據commit message 自動生成一份CHANGELOG.md文件
再配合上package.json
裏的scripts
{
"scripts": {
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
}
}
複製代碼
只須要執行npm run changelog
就好了,是否是很簡單?
可是該在什麼時機執行上面這條命令呢?
根據文檔推薦的工做流,在修改package.json
中的版本以後執行最合適。
不過在下面的版本控制會將工做流改爲用npm version
來實現。
{
"scripts": {
"version": "npm run changelog && git add CHANGELOG.md"
}
}
複製代碼
傳統版本迭代步驟
package.json
中修改遞增version
git add -A
git commit -m "update version"
git push
git tag <tag version>
git push --tag
npm publish
流程過於繁冗,很容易遺漏打tag那一步。
使用npm version
命令,從文檔上咱們能夠看到其依據semver支持了大部分alias:
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]
複製代碼
例:初始版本爲1.0.0
npm version prepatch
//預備補丁版本號 v1.0.1-0
npm version prerelease
//預發佈版本號 v1.0.1-1
npm version patch
//補丁版本號 v1.0.2
npm version preminor
//預備次版本號 v1.1.0-0
npm version minor
//次版本號 v1.1.0
npm version premajor
//預備主版本號 v2.0.0-0
npm version major
//主版本號 v2.0.0
當在倉庫中執行npm version時
,會自動提交git commit
並打上git tag
。
當使用
-m
參數時,就能夠自定義發佈版本的信息,其中%s
能夠用來代替當前版本號npm version patch -m "upgrade to %s for reasons" 複製代碼
這樣之後版本迭代只須要如下步驟
npm version patch | minor | major | ...etc
git push
git push --tag
npm publish
如何發佈beta,rc,alpha版本呢?若是發佈了,應該如何安裝?
首先咱們要理解這些版本的含義
而後將package.json
的version
改爲x.x.x-beta
配合npm publish --tag <tag>
,咱們能夠發佈對應的dist-tag
舉個例子:
使用
npm publish --tag beta
發佈後,而後就可使用npm install <pkg>@beta
安裝對應版本的包。
咱們能夠經過npm dist-tag ls <pkg>
來查看包的dist-tag
{
latest: 1.0.1, // 這就是npm publish默認發佈的tag
beta: 1.0.1-beta
}
複製代碼
當咱們的beta版本穩定後,可使用npm dist-tag add x.x.x-beta latest
設置爲穩定版本。
正常工做流咱們分爲兩塊:
開發流程
在開發流程中,咱們須要保障:
發佈流程
在發佈流程中,咱們須要保障:
根據上述兩種流程,咱們可使用git hook
和npm hook
在上面已經介紹過,咱們選用husky做爲git hook
的實現工具
npm install -D husky
複製代碼
代碼lint和單元測試,咱們能夠放到precommit
中執行,修改鉤子執行的命令
{
"scripts": {
"test": "jest",
"precommit": "lint-staged && npm run test"
}
}
複製代碼
commit message lint的解決方案:commitlint
npm install -D @commitlint/config-conventional @commitlint/cli
複製代碼
而後在package.json
中配置鉤子
{
"scripts": {
"commitmsg": "commitlint -E GIT_PARAMS"
},
"commitlint": {
"extends": ["@commitlint/config-conventional"],
"rules": {
"subject-case": [0]
}
}
}
複製代碼
這樣咱們在git commit
執行以前驗證了eslint
是否經過,測試用例是否經過,commit message
是否符合規範。
固然也能夠在
commit
後面添加參數--no-verify
來跳過commit message lint
bump version
修改package.json
{
"scripts": {
"version": "npm run changelog && git add CHANGELOG.md",
"postversion": "git push && git push --tags"
}
}
複製代碼
而後執行npm version patch | minor | major
npm publish
添加prepublishOnly hook
{
"scripts": {
"prepublishOnly ": "npm run build"
}
}
複製代碼
而後執行npm publish
執行
npm version
命令時會依次執行npm script
中的preversion
,version
,postversion
三個鉤子,具體詳情見文檔
prepublishOnly
只會在npm publish
以前執行,prepare
和prepublish
都會在npm publish
和不帶參數的npm install
時執行,見npm script文檔
至此,咱們已經基本打造了一個比較完善的開源項目workflow。
對於項目開發者來講,只須要作如下幾點改變:
eslint
和editorconifg
插件git cz
提交信息npm version patch | minor | patch
來進行版本迭代是否是更簡單方便了呢?
歡迎你們拍磚,廣納良言!