從0到1發布一個npm包

  • 2019 年 10 月 3 日
  • 筆記

從0到1發布一個npm包
author: @TiffanysBear

最近在項目業務中有遇到一些問題,一些通用的方法或者封裝的模組在PC、WAP甚至是APP中都需要使用,但是對於業務的PC、WAP、APP往往是不同的業務、不同的程式碼庫中,儘管已經將公用的組件和方法抽離到各自公共common中,但是各個大業務大方向上的公用封裝依然不能滿足需求。

比如一個計算文檔類型大小的方法,可能都同時存在於各個業務的common中,假設是有3處程式碼庫中均有;如果此時的需求是將文檔類型或者大小的方法進行一些修改,增加一種文檔類型或者減少一種文檔類型,那咱們是否是需要去共同修改上面的3處方法。這樣做,很不利於程式碼的維護,浪費人力,增加了程式碼工作量。

那麼,如何做到管理一些公共依賴的基礎模組程式碼呢?這時候,封裝發布一個npm包進行統一管理就是一個很好的辦法了。

先po一下我在寫這篇文章時,根據以下的步驟發布的一個簡單封裝的npm包以及github地址,大家可以先看:

npm包:page-performance-monitor
github地址:page-performance-monitor,歡迎 star、issue

下面,就從0開始講起,如何從0到1發布一個npm包。先介紹一下什麼是npm~

npm

npm 是JavaScript 世界的包管理工具,並且是Node.js 平台的默認包管理工具。通過npm 可以安裝、共享、分發程式碼,管理項目依賴關係。

官網地址

比如有一些非常通用的公用方法,抽象封裝,剔除一些冗餘的業務需求,可以封裝在一個npm包中,提供給相應的多個業務去使用。

那麼接下來就列舉一下封裝一個簡單的封裝步驟;

發布步驟

以我之前的部落格中列舉的頁面性能監控工具performance為例,具體的performance介紹可以點擊鏈接,做一個簡單的封裝,滿足基本的業務上的打點統計需求即可;後面也會講到後續如何去封裝一個高品質的npm包,比如加上一些example、測試test、完善README.md等,逐步去完善。大概是有以下幾個步驟:

1、新建項目,準備需要發布的程式碼
2、準備package.json
3、註冊npm帳號、並登錄
4、發布

其實發布的過程並不難,要發布一個好的品質高的npm包往往是取決於要封裝的程式碼、以及對程式碼單測覆蓋、demo案例、README介紹等

準備項目:

開始準備的步驟,從一個最基礎的項目新建開始,都是在Mac的Linux環境上進行:

// 新建項目文件夾   mkdir page-performance      // 初始化npm,初始化package.json   npm init      // 準備好封裝程式碼   // 一般源碼是放在src,通過其他打包工具生成的一般是在dist目錄或者build目錄   mkdir src      // 可以將自己需要的程式碼往src中添加了   // 假設我們只需要發布一個index.js就好   // ......

發布一個最簡單的npm包:

1、先去官網註冊一個帳號,填寫好帳號、密碼、郵箱
2、然後登錄npm帳號 npm login,如果你們公司有自己的默認npm倉庫或者使用的淘寶鏡像,注意需要指定一下倉庫地址;npm login --registry=https://registry.npmjs.org

# 會依次讓你輸入用戶名、密碼、和郵箱  Username:  Password:  Email: (this IS public) 

3、發布包 npm publish --registry=https://registry.npmjs.org

會提示+ [email protected] 你的包名字和版本,那麼說明就發布好了。

我在發布的時候遇到了兩個小問題,記錄一下,如果你們也有相同的問題,可以使用下面的解決辦法:
1). 提示 publish Failed PUT 403

you must verify your email before publishing a new package: https://www.npmjs.com/email-edit : page-performance-monitor

之前登錄的郵箱需要驗證,去註冊郵箱中找到npm發的郵件,點擊驗證一下就行.

2)第二個問題是:You do not have permission to publish "page-performance". Are you logged in as the correct user? : page-performance

提示是說你沒有許可權發布這個包,其實是因為你的這個包名字和已有的重複了,需要在 package.json 裡面換一個包名就行。

到這裡,一個簡單的npm包就封裝好了,如何確認自己的包確認好了呢?去官網的搜索框輸入你的包名搜一下,找到你的就ok啦~

到這步,你就會發布一個簡單的npm包啦,如果只是一個很小的需求的化,就完全夠用了;但是如果想要發布一個品質好有各種小標籤logo的,那麼就需要如下的步驟進行一下優化。

優化npm包:

1、程式碼環境依賴-線上線下環境

如果項目在線上線下使用的配置都不同的化,可以通過命令輸入的不同,區分是debug模式還是生產production模式。

process.env.NODE_ENV === 'production'

在相應的package.json中的配置中,就需要加上 npm run build --mode production 來進行區分。

2、配置打包編譯

好的一個npm包,往往需要不同的產出模式,比如利於script標籤使用的iife模式,或者是採用amd、cmd等的打包方式進行export;或者需要採用babel進行轉義,增加polyfill;或者你需要增加demo,為demo輸出不同的樣例,都需要使用配置打包編譯。

目前常見的打包編譯工具有webpack、rollup、fis、gulp等工具,相信也非常熟悉了;因為我的這個只是個簡單的檢測頁面性能的工具方法,採用較為簡單的適合工具庫類型打包的rollup進行打包編譯。

rollup.config.js配置如下:

/**   * @file: rollup.config.js   * @author: Tiffany   */  // Rollup plugins  import resolve from 'rollup-plugin-node-resolve';  import commonjs from '@baidu/rollup-plugin-commonjs';  import babel from 'rollup-plugin-babel';  import uglify from 'rollup-plugin-uglify-es';  export default [      {          input: 'src/index.js',          output: {              file: 'dist/index.js',              format: 'umd',              name: 'Perf',              legacy: true,              strict: false,              sourceMap: true          },          plugins: [              resolve(),              commonjs(),              babel({                  runtimeHelpers: true,                  exclude: 'node_modules/**'              }),              uglify()          ]      }  ];  

配合babel的配置,如下:

{      "presets": [          [              "latest",              {                  "es2015": {                      "modules": false                  }              }          ]      ],      "plugins": [          "external-helpers"      ]  }

然後就可以根據自己的需求,選擇打包format的模式,產出自己需要的結果。大家也可以根據自己的項目需求、大小等,進行配置。

3、增加單測

現在前端單測的庫有很多,在這裡就不再贅述;在這裡採用的是 mocha + chai 斷言庫,因為這個庫是運行在瀏覽器端,需要依賴於 JSDOM 中的 window 對象,因為採用了 JSDOM 庫來實現 DOM 對象等的構建以及全局變數 window 的加入,以下是具體的配置:

// test/index.test.js    /**   * @file: index.test.js   * @author: zhoufang04   * @description: mocha + chai test   */    const expect = require('chai').expect;  const {JSDOM} = require('jsdom');  const perf = require('../dist/index.js');  const {window} = new JSDOM(`<!DOCTYPE html>      <html>      <head>          <meta charset="UTF-8">          <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0, maximum-scale=1.0,user-scalable=no">          <meta name="author" content="test">          <title>performance test</title>      </head>      <body>          <div id="values"></div>          <div id="app"></div>      </body>      </html>`);    global.window = window;    describe('頁面性能測試', function () {      it('載入完成返回數據為對象', function () {          expect(perf.getPerformanceTiming()).to.be.an('object');      });      it('返回耗時', function () {          expect(perf.getPerformanceTiming().duration).to.be.an('number');      });      it('返回ttfb耗時', function () {          expect(perf.getPerformanceTiming().ttfb).to.be.an('number');      });      it('返回requestTime耗時', function () {          expect(perf.getPerformanceTiming().requestTime).to.be.an('number');      });  });    

運行node ./node_modules/mocha/bin/mocha,效果如下圖:

需要注意的是,本地node版本太低可能會導致mocha會有報錯,這時候採用 nvm 升級一下node版本,再次運行就行。

4、增加Example

增加example文件夾,裡面可以通過對這個包的使用,增加一些Demo案例,讓別人能更好的知道怎麼使用這個庫。

5、完善README.md

在項目文件中增加README.md,提供使用方法、demo、注意事項等資訊,方便別人使用,更容易讓人明白。

可以看下在 page-performance-monitor 這個庫中,我這邊寫的README.md,點擊鏈接可查看

總結

上面的步驟就是如何從0到1封裝的一個npm包,可以封裝一個簡單的適於業務快速開發的,也可以封裝一個高品質封裝一起使用;可以根據自己的業務需求、時間成本等自行選擇。