最近寫 node
的時候遇到一個需求,需要清理某目錄下超過3天圖片,本來想在 npm
找個包直接用用,結果沒找到合適的,於是就自己擼一個了。
本文主要講述如何從零開始開發一個完善健壯的 npm
包,主要涉及到一些工具的使用配置,包的功能不是重點。
一、配置eslint
ESLint是一個程式碼風格檢測工具,比如使用空格還是tab,要不要加分號,使用駝峰命名還是下劃線等等。可以保證一個團隊的程式碼風格保持一致。
npm install eslint -g
eslint init
根據 eslint
提供的選項結合自己的需求,一路選擇好後,會在根目錄建立一個 .eslintrc.json
檔案,裡面一系列的規則配置,這個時候你再寫程式碼,如果不符合規範,編輯器就會報錯提示,如果某些目錄不想使用校驗,可以建立一個 .eslintignore
,把不需要校驗的目錄放進入。為了方便執行校驗,我們在 package.json
裡配置一下 scripts
:
"scripts": {
"lint": "eslint --fix src"
}
可以配合githook強制每次提交的時候校驗程式碼:使用git鉤子做eslint校驗
二、編寫程式碼
我們在src目錄下編寫我們的程式碼,拆分成具體步驟為
- 讀取目錄下所有檔案
- 篩選出我們需要處理的檔案,比如建立或者修改時間超過3天的圖片或者日誌
- 刪除這些檔案
我們分成3個函式:
// readAllFileInfo.js
// 使用fs.readdir讀取目錄下所有檔案
fs.readdir(filePath, function(err, files) {
if (err) {
reject(err);
} else {
Promise.all(files.map(file => {
return filterFile(file, options);
}))
.then(deleteFiles => {
resolve(deleteFiles.filter(deleteFile => deleteFile));
});
}
});
// filterFile.js
// 使用fs.stat讀取檔案資訊,然後篩選出需要刪除的檔案
fs.stat(fileName, (err, stats) => {
if (err) {
reject(err);
} else {
const time = stats[expiredType];
const distanceTime = formatDate(date);
const extName = path.extname(fileName);
if (now - time > distanceTime && extName === `.${ext}`) {
deleteFile(fileName)
.then((res) => {
resolve(res);
});
} else {
resolve();
}
}
});
// deleteFile.js
// 使用fs.unlink刪除檔案
fs.unlink(fileName, err => {
if (err) {
reject(err);
} else {
resolve(fileName);
}
});
這裡主要講一下解決問題的思路,首先整理一下解決這個問題需要哪些步驟,然後每一個步驟可以抽象成一個函式,想一下函式的傳參和返回值,最後可以設計一下更加相容易擴充套件的 API
,具體程式碼可以檢視倉庫:https://github.com/wulv/del-e…。
三、使用babel
在低版本的 node
可能還不支援某些 es6
語法,比如物件解構等,所以需要使用 babel
編譯成低版本也能識別的語法。我們把 src
目錄裡的程式碼編譯到 lib
目錄,然後我們在 package.json
裡,把 "main"
改為 "lib/index.js"
,這樣對外暴露出去的程式碼就不會出現相容性問題。
下載 babel-cli
依賴:
npm install --save-dev babel-cli
// 下載預設,預設就是別人配置好的一系列規則,編譯在規則內的語法
npm install --save-dev babel-preset-es2015
配置好 .babelrc
:
{
"presets": ["es2015"]
}
在 package.json
裡配置一下 scripts
:
"scripts": {
"build": "babel src -d lib",
"build:watch": "npm run build -- --watch"
}
這樣執行 npm run build
就會編譯原始檔到 lib
目錄了。
四、編寫測試
為了保障程式的穩定性,我們一定要寫測試用例,特別是當你的程式依賴越來越多的時候,比如你改了A模組,你覺得你的改動都沒問題,但一發布出去就會出現意想不到的 bug
因為影響到了你不知道的某個模組。這個時候測試就尤為重要,可以幫你避免很多低階錯誤。我們使用 mocha
和 chai
做測試框架和斷言,下載依賴。
npm install mocha chai --save-dev
我們在專案根目錄建立一個 test
目錄。建立 index.formatDate.js
,內容為:
`use strict`;
const chai = require(`chai`);
const formatDate = require(`../lib/formatDate`);
const expect = chai.expect;
const S = 1000;
describe(`format dete`, () => {
it(`test 2s`, function() {
expect(formatDate(`2s`)).to.be.equal(2 * S);
});
});
這裡只是演示一下基本的語法,程式碼太多,具體看倉庫。然後在 package.json
裡再新增一個 scripts
:
"test": "npm run build && mocha -t 5000"
五、Travis-CI+Coveralls
Travis-CI
是一個持續整合構建專案,結合github
可以實現很強大的功能,比如你給一個倉庫提交 PR
後,可以自動幫你跑完測試用例,如果測試沒有通過,就不能 merge
到 master
,Coveralls
是一個自動化測試覆蓋率的服務,用於收集測試覆蓋率報告,對於開源專案免費,配置好這個後,就可以生成一個顯示你程式碼測試覆蓋率的 badge
。Coveralls
可以使用 GitHub
賬號登入,登入之後可以在 https://coveralls.io/repos/new 新增需要收集報告的 repo
。
首先安裝一下 istanbul
這個工具來檢測程式碼的測試覆蓋率:
npm install istanbul --save-dev
然後在 package.json 中的 scripts 裡新增:
"cover": "istanbul cover node_modules/mocha/bin/_mocha"
執行 npm run cover
就可以看到你的程式碼測試覆蓋率了
========= Coverage summary =========
Statements : 92.65% ( 63/68 )
Branches : 75% ( 15/20 )
Functions : 100% ( 14/14 )
Lines : 92.65% ( 63/68 )
====================================
將測試覆蓋率報告提交給 Coveralls
,首先安裝 coveralls
:
npm install coveralls --save-dev
然後在 package.json
中的 scripts
裡新增
"coveralls": "npm run cover -- --report lcovonly && cat ./coverage/lcov.info | coveralls"
然後建立 .travis.yml
檔案,
sudo: false
language: node_js
os:
- linux
- osx
node_js:
- 6
- 8
- 9
- 10
branches:
only:
- master
install:
- npm install
script:
- npm run lint
- npm run build
- npm run cover
after_success:
- npm run coveralls
將程式碼推到 github
後,開啟 https://travis-ci.org/ ,點開右上角頭像 -> profile,把自己倉庫的開關開啟:
在 README.md
裡新增程式碼測試覆蓋率的 badge
,我們可以使用 http://shields.io 來新增 badge
,比如還有下載量,star數等這些badge
。
[![Build Status](https://travis-ci.org/wulv/del-expired-file.png)](https://travis-ci.org/wulv/del-expired-file)
[![Coverage Status](https://img.shields.io/coveralls/wulv/del-expired-file/master.svg?style=flat)](https://coveralls.io/github/wulv/del-expired-file?branch=master)
最終可以看到以下效果,當你看到一個 npm
如果顯示了測試覆蓋率,是不是頓時放心很多了呢?
六、釋出
至此我們基本已經寫好了一個相對比較健壯的倉庫了,現在釋出到 npm
上,如果沒有 npm
賬號的話,需要先註冊一下,然後執行
npm adduser
輸入使用者名稱和密碼,npm publish
,這樣你的倉庫就釋出好了,如果要更新版本,要遵循 Semver(語義化版本號)
規範:
- 升級補丁版本號:npm version patch
- 升級小版本號:npm version minor
- 升級大版本號:npm version major
總結
總結一下上面使用到的工具和技術:
我們可以看到,如果只是實現功能,把目標定在僅僅實現需求上,寫這個 npm
包,用一個檔案三個函式就完成了,但是這樣的話,這個包估計也就只有你自己用了,以後的維護,修改都會比較麻煩,而使用這一套工具後,就健壯很多了。工作上也是這樣,我們需要追求卓越,不斷打磨自己的手藝,做出更完美的作品。
打個廣告,杭州有贊誠招前端開發工程師,我們在4月舉辦了一次前端技術開放日,詳情檢視連結:https://tech.youzan.com/fe-op…。公司福利多多:
- 標配:
MacBook
,報銷:螢幕、滑鼠、機械鍵盤- 五險一金、980元/月的餐補、加班叫車費報銷、年度
outing
和體檢、每人每年有機會參加外部大會/培訓等- 各種高大上的聚餐、千奇百怪的團建,長期投食的零食架…
- 高配電視、遊戲機、桌球、乒乓球、檯球、健身器械,還有四驅賽道等,等你來戰~
有意向的話請傳送簡歷到wulv#youzan.com
。