如何釋出一個 npm 包

大芒果哇發表於2020-05-31

一 背景

在工作時,突然接到經理的一個要求,需要將一個react的高階元件函式封裝成一個npm包。之前從沒弄過,當場還是有些懵逼的,但是這畢竟是工作,不能推脫。於是開始了學習、湯坑之旅。最終包釋出,線上專案成功使用,雖然導致了一次線上故障,但還是快速地fix掉。吃一塹長一智,記錄一下整個釋出的過程和遇到的一些問題。

二 流程

npm 包可以將可複用邏輯封裝成一個工具庫,依賴 npm 的強大生態,可以在專案中引入,讓程式碼變得更加簡潔,提高效率。

  1. 在 npm 官網註冊一個賬號。
  2. 在本地登入 npm 賬號。
  3. 編寫 npm 包內容。
  4. 釋出包。

三 開發過程

1 註冊npm賬號。附錄網站: https://www.npmjs.com/

2 在本地登入npm賬號。

npm login

輸入在npm官網註冊的賬號密碼即可。

3 編寫npm包

3.1 執行以下命令,建立一個npm模組

mkdir npmDir
cd npmDir
npm init -y

3.2 安裝webpack

npm install webpack webpack-ci -D

在本地開發時,通常考慮更多的是程式碼的可讀性,以便於在邏輯出錯時,可debug其原始碼找到問題。然而發至線上時,則考慮更多的是包的體積,越小即代表著更快的載入。
同時,一個強大的包應該支援多種方式匯入,例如es module的import,commonjs的require以及amd的古老方式。
為做到以上兩點,選擇了webpack作為構建工具。雖然用webpack個人感覺稍微有點重,但是它可擴充套件性強,日後利用loader以及plugin可以實現更多的編譯以及優化需求。

3.3 梳理專案目錄


src下的index.js對應著包的內容。
最外層index.js為所暴露的出口檔案。
dist目錄存放webpack打包後的檔案。

3.4 編寫對應內容

3.4.1 webpack.config.js

  1. mode 為支援開發版程式碼不壓縮,線上版本壓縮。此處將mode設定為'none',預設全不壓縮,然後自己用外掛來配置壓縮程式碼檔案。

  2. entry設定兩個入口,add為在開發時匯入,add.min檔案為線上上時匯入。

  3. output設定。

    • filename: 設定佔位符。預設為entry入口檔名字
    • library: 庫的返回值賦值給變數或者屬性 add。例如script引入方式,則可以全域性使用add函式。此屬性和library配合使用
    • libraryTarget: 變數暴露的方式。設定為umd即可支援es module、cmd以及script引入指令碼的方式使用。
    • libraryExport: 配置要匯出的模組中那些子模組需要被匯出。只有output.libraryTarget被設定成commonjs或者commonjs2的時候才有效。我的匯出方式是export default,因此我將其直接匯出。如果不填此項,則預設引入的是module物件。呼叫方式會是 .default形式。
  4. optimization設定
    利用TerserPlugin外掛進行壓縮程式碼,預設只壓縮.min結尾的輸出檔案。

3.4.2 模組主要內容 src/index.js


簡單的一個測試函式

3.4.3 main入口檔案index.js


根據環境變數自動引入相關版本。

3.4.4 構建命令。package.json


釋出包時可以手動執行build命令後後釋出,也可通過prepublish鉤子自動編譯然後釋出。

4 釋出包

修改 package.json 中的name欄位,即包在npm中的名字。小提示,想好名字之後,最好到npm官網上搜尋一下這個包有沒有被別人註冊,有的話就要換一個了。
修改版本號,可手動修改,也可通過npm version命令進行更換。個人習慣於後面。

# 修改版本號
npm version major | minorr | patch
# 釋出包到npm
npm publish

然後在npm官網上搜尋一下,便可以找到你釋出的包了。開心。

四 遇到的問題

4.1 在服務端渲染(ssr)的專案中引入該包時,會報錯誤 ”window is not defined“

本以為是包中程式碼邏輯錯誤,把專案中所有引入到window的地方全都用typeof相容了一遍,本想完事大吉,結果還是報這個錯誤。上網搜尋各種帖子無效之後,我感覺是webpack編譯打包後出了問題,於是報著試一試的心態去看編譯後的未壓縮版本程式碼,果然發現了問題。

如圖所示,打包後的檔案為一個自執行匿名函式,函式第一個實參竟然是window。
於是去webpack官網檢視相關文件,看其是否能配置。果然找到了
-w728
修改globalObject屬性,將第一個引數設定為this,解決問題。

附錄
gihub: https://github.com/ShengGaoW/shenggao-test-npm

相關文章