從零開發一個健壯的npm包

最近寫 node 的時候遇到一個需求,須要清理某目錄下超過3天圖片,原本想在 npm 找個包直接用用,結果沒找到合適的,因而就本身擼一個了。html

本文主要講述如何從零開始開發一個完善健壯的 npm 包,主要涉及到一些工具的使用配置,包的功能不是重點。前端

1、配置eslint

ESLint是一個代碼風格檢測工具,好比使用空格仍是tab,要不要加分號,使用駝峯命名仍是下劃線等等。能夠保證一個團隊的代碼風格保持一致。node

npm install eslint -g
eslint init
複製代碼

根據 eslint 提供的選項結合本身的需求,一路選擇好後,會在根目錄建立一個 .eslintrc.json 文件,裏面一系列的規則配置,這個時候你再寫代碼,若是不符合規範,編輯器就會報錯提示,若是某些目錄不想使用校驗,能夠建立一個 .eslintignore,把不須要校驗的目錄放進入。爲了方便執行校驗,咱們在 package.json 裏配置一下 scripts:linux

"scripts": {
  "lint": "eslint --fix src"
}
複製代碼

能夠配合githook強制每次提交的時候校驗代碼:使用git鉤子作eslint校驗git

2、編寫代碼

咱們在src目錄下編寫咱們的代碼,拆分紅具體步驟爲es6

  1. 讀取目錄下全部文件
  2. 篩選出咱們須要處理的文件,好比建立或者修改時間超過3天的圖片或者日誌
  3. 刪除這些文件

咱們分紅3個函數:github

// 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-expired-file。npm

3、使用babel

在低版本的 node 可能還不支持某些 es6 語法,好比對象解構等,因此須要使用 babel 編譯成低版本也能識別的語法。咱們把 src 目錄裏的代碼編譯到 lib 目錄,而後咱們在 package.json 裏,把 "main" 改成 "lib/index.js",這樣對外暴露出去的代碼就不會出現兼容性問題。json

下載 babel-cli 依賴:bash

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 目錄了。

4、編寫測試

爲了保障程序的穩定性,咱們必定要寫測試用例,特別是當你的程序依賴愈來愈多的時候,好比你改了A模塊,你以爲你的改動都沒問題,但一發布出去就會出現意想不到的 bug 由於影響到了你不知道的某個模塊。這個時候測試就尤其重要,能夠幫你避免不少低級錯誤。咱們使用 mochachai 作測試框架和斷言,下載依賴。

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"
複製代碼

5、Travis-CI+Coveralls

Travis-CI 是一個持續集成構建項目,結合github 能夠實現很強大的功能,好比你給一個倉庫提交 PR 後,能夠自動幫你跑完測試用例,若是測試沒有經過,就不能 mergemasterCoveralls 是一個自動化測試覆蓋率的服務,用於收集測試覆蓋率報告,對於開源項目免費,配置好這個後,就能夠生成一個顯示你代碼測試覆蓋率的 badgeCoveralls 可使用 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 若是顯示了測試覆蓋率,是否是頓時放心不少了呢?

6、發佈

至此咱們基本已經寫好了一個相對比較健壯的倉庫了,如今發佈到 npm 上,若是沒有 npm 帳號的話,須要先註冊一下,而後運行

npm adduser
複製代碼

輸入用戶名和密碼,npm publish,這樣你的倉庫就發佈好了,若是要更新版本,要遵循 Semver(語義化版本號) 規範:

  1. 升級補丁版本號:npm version patch
  2. 升級小版本號:npm version minor
  3. 升級大版本號:npm version major

總結

總結一下上面使用到的工具和技術:

咱們能夠看到,若是隻是實現功能,把目標定在僅僅實現需求上,寫這個 npm 包,用一個文件三個函數就完成了,可是這樣的話,這個包估計也就只有你本身用了,之後的維護,修改都會比較麻煩,而使用這一套工具後,就健壯不少了。工做上也是這樣,咱們須要追求卓越,不斷打磨本身的手藝,作出更完美的做品。

打個廣告,杭州有贊誠招前端開發工程師,咱們在4月舉辦了一次前端技術開放日,詳情查看連接:https://tech.youzan.com/fe-open-day-2018/。公司福利多多:

  • 標配:MacBook,報銷:顯示屏、鼠標、機械鍵盤
  • 五險一金、980元/月的餐補、加班打車費報銷、年度outing和體檢、每人每一年有機會參加外部大會/培訓等
  • 各類高大上的聚餐、千奇百怪的團建,長期投食的零食架...
  • 高配電視、遊戲機、桌球、乒乓球、檯球、健身器械,還有四驅賽道等,等你來戰~

有意向的話請發送簡歷到wulv#youzan.com

參考連接

相關文章
相關標籤/搜索