主頁 > 企業開發 > 如何撰寫一個健壯的 npm 包

如何撰寫一個健壯的 npm 包

2023-05-25 14:04:45 企業開發

無腦發布 npm

比如老王我,用npm init新建一個包,改把改把,然后來個npm publish,so easy ??!

Too young too naive, baby ??!

請容我講述一些發布程序中踩過的坑,

首先,算了也可以之后有空再說,我們需要通讀npm的配置檔案,

package.json doc

通用性??

指定發布檔案

利用package.jsonfiles欄位精簡發布體積,

{
  "files": ["dist", "lib", "module"]
}

若不指定files,每次發布會把所有不以.開頭的檔案都發布出去,導致發布體積過大(node_modules默認也不會被發布),

README.md作為主檔案,加不加都會發布,package.json也是,

指定源代碼

{
  "source": "src/index.ts",
  "repository": {
    "type": "git",
    "url": "https://github.com/yourname/yourproject.git"
  }
}

通常來說我是不在npm發布中包括源代碼的,因此都沒有加過source欄位,只是用repository來告知一下git倉庫地址即可,

如果倉庫是內部倉庫或私人倉庫并不對外,則source欄位就有用了,將源代碼發布后可讓人幫忙debug找問題,

注意如果有source,則files也要加上souce對應的檔案或檔案夾,

發布sourcemap

一般來說我們發布的都是經過編譯的代碼,為了給使用者方便除錯,只要不是原始碼,都要有對應的sourcemap檔案,例如發布了一個dist/index.js則也需要一個dist/index.js.map檔案與之配套,

指定安裝源

如果你從來不用私有源,可跳過該項,

利用.npmrc指定安裝源,用于當前專案與你的全域配置區分開,

否則當前專案很可能指定的內部npm源,導致外部用戶無法利用lock檔案安裝,

例如

registry=https://registry.npmjs.org/

精確指定dependenciesdevDependenciespeerDependencies

dependencies要盡量少,只有在運行時確實用到才放進去,

依賴的版本號要清晰指明,如"react": "16.x || 17.x"

否則,如果指定了"react": "17.0.0",則在使用了react 16的專案中,會引入兩份react,造成一些莫名其妙的問題,

這種情況,react應放到peerDependencies中,

指定發布目標

如果你從來不在私有源發布,可跳過該項,

package.json中指定發布地址,在當前包與全域配置不一致時非常必要,

{
  "publishConfig": {
    "registry": "https://registry.npmjs.org"
  }
}

sideEffects

對應配置:

{ "sideEffects": false }

作用:在打包時進行treeshake可根據是否使用而優化相關的代碼,

如果sideEffectstrue,則一旦引入,不管是否呼叫都不能被treeshake掉,

專用性??

型別配套

無論針對哪個環境,目前自帶型別已經是既成事實的標配,

記得生成型別的.d.ts檔案,并在package.json中指定,

{
  "types": "type/index.d.ts",
  "typings": "type/index.d.ts"
}

我一般會用一個專用的tsconfig.declaration.json來專門生成型別:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "noEmit": false,
    "emitDeclarationOnly": true,
    "declaration": true,
    "outDir": "types"
  }
}

作為后端庫

package.json中指定main欄位,

編譯結果需要在nodejs環境中運行,輸出commonjs格式模塊,

為了兼容最新與將來,同時也要輸出esmodule格式模塊,

相關配置:

{
  "main": "lib/index.js",
  "module": "module/index.js",
  "jsnext:main": "module/index.js"
}

modulejsnext:main都是指esmodule格式,只是為了兼容某些特殊環境的別名,可能還有其他別名單我暫時就見過這倆,

其中module中的檔案推薦使用特定的后綴名,例如.esm.js.mjs,但在一些工程相關工具中是否會有未知為題,不好說,

未來已來,現在大部分前端工程工具都會優先使用module指定的檔案,單如果沒有指定module,也會為了兼容去加載main

作為前端庫

前端庫其實要求比后端庫更高,為啥?

因為現代前端開發環境要求支持所有后端環境,并延伸出前端環境的額外支持,也就是說后端庫要求一般是前端庫要求的子集,

需要擴展的是純前端環境的運行格式,老格式amd已經被淘汰可以不用考慮,現在基本都被umd格式統一,

{
  "main": "lib/index.js",
  "module": "module/index.js",
  "unpkg": "dist/index.js",
  "umd:main": "dist/index.js",
  "jsdelivr": "dist/index.umd.production.min.js"
}

其中unpkgumd:mainjsdelivr都是為了更廣泛兼容的指向瀏覽器環境運行的同一個目標別名,

通常來說commonjsesmoduleumd都不會將其依賴的其他包包括進去,只是在運行時才加載,

還有一種情況,可能只有我自己用到過,就是發布包中有些東西與外部環境有沖突,因此除了這些通用模式之外我又加了一個independent(取名叫standalong也比較合適)格式,將這個包的所有依賴都封裝進去,可以不依賴外部環境獨立使用,

例如mobx-value的獨立運行檔案,

mobx-value independent

注意瀏覽器環境輸出的都是優化后的.production.min格式,也必須同時輸出.development后綴的開發模式,為了方便使用者除錯方便,

因為最大的使用者,往往就是我們自己,不要連自己都糊弄了事~

作為命令列工具

多配置兼容

命令列工具一般需要很多引數,例如tsc,當引數過多時沒人愿意每次都輸入長長的引數,因此需要組態檔的支持,

那么選哪種配置格式呢?

此時cosmiconfig隆重登場!以一句名言形容,小孩子才做選擇,成年人全都要!

兼容各種配置,各種位置,詳情參見其api

還有一點,如果需要讀取一些周邊的json配置,不要用原生的JSON.parse,很多json是帶注釋的或者撰寫不規范,用json5讀取兼容好,

還有一個精簡版:lilconfig,功能差不多,我下次打算試試,

配置檔案型別校驗

剛入門typescript時,我嘗試用typescript作為組態檔,然后在運行時利用型別機制達到校驗配置的目的,

但這樣會丟失很多靈活性,限制死了組態檔的來源與格式,并由于庫的typescript環境與應用所在的typescript環境不一致,也導致了很多工程問題(對我說的就是ts-gear),

后來發現通過注釋檔案的方式,js檔案中也同樣可以校驗型別,而且js檔案對運行時更友好,

例如webpack.config.js這樣配置

/**
 * @type {import('webpack').Configuration}
 * */
const config = {...}
export default config

組態檔運行時校驗

我們的程式要讀配置,但配置是使用者提供的,誰知道用戶會寫些什么,即使有上面那步提到的型別校驗把關,也會有很多邊界問題型別根本管不了,

因此,運行時配置資料校驗就是必備環節,

不光是校驗不通過時終止運行,還必須給出一個合理且精準的錯誤提示,

推薦一個協議、兩個校驗工具與一個漂亮的格式化提示工具,

協議是json schema,校驗工具為joiajv,提示輸出工具為chalk

指定可運行檔案

package.json中指定bin

{
  "bin": "bin/run.js"
}

對于大部分js腳本,都要在運行檔案頭部指定運行環境,

#! /usr/bin/env node

然后別忘了在發布前添加可執行屬性,務必整合在自動化發布腳本中,

chmod +x bin/run.js

可呼叫api

例如babel,我們不光能使用@babel/cli在命令列使用,也可以在自己的程式里import babel from 'babel'來呼叫其api

一個命令列工具通常也是一個第三方庫,方便集成到呼叫者自身的腳本與環境中,

其他特定環境

例如針對react-native,這個我就見過,沒實際用過,

{
  "react-native": "dist/index.esm.js"
}

最后不論什么格式,都記得輸出配套sourcemap.map檔案,

健壯性??

指定運行環境:engine與os

尤其對于命令列工具,這倆點很重要,不然很容易就換個人換個電腦就莫名報錯,

{
  "engine": "node>=14",
  "os": ["linux", "darwin"]
}

有否配套測驗用例

  • 有可運行的配套測驗用例,
  • README.md上有可見的測驗覆寫率統計,讓人可以放心使用,

測驗用例放在哪?

最初我習慣按照jest推薦的模式,將所有測驗用例放在__tests__檔案夾內,

最近兩年看了好多別的語言的單測用例,我現在更傾向于將測驗檔案與源檔案放在一起,因為測驗用例,就是源代碼的一部分!

比如以下這種目錄結構

src/setter.ts
src/setter.test.ts

測驗運行時機

npm prepublishOnly的鉤子一定要加上運行測驗用例,

有余力的情況,可以再配置個額外的流水線,github上有好多免費的配套流水線,自己折騰折騰,

代碼校驗配套

專案必須有一個較好的檔案規則校驗流程,大多數情況我使用eslint,然后配上airbnbprettier的校驗規則,

校驗有兩個重要作用,一個是真的能解決很多隱性bug,另一個是代碼漂亮,之后看你專案原始碼的人也會覺得舒服,關鍵是面試時也能拿的出手,

如果有面試者給我看自己的開源作品,如果代碼風格都不行,立即就判定不行,也不用再看什么邏輯能力了,招進來也是挖坑,

好的代碼風格必須依賴校驗工具,最好把校驗流程也集成到發布的鉤子上,

推廣性??

檔案

使用.markdownlint配置規范自己的markdown檔案,否則很容易寫飛了,

要不人家一看檔案,專案質量很容易就露餡了不是??

配套展示用例

  • 一個方法是在專案中自帶一個可運行的樣例,讓人clone之后運行指定命令即可查看樣例,
  • 更好一些,部署一個可以在線查看的例子,并在主檔案上附上直達鏈接,
  • 更進一步,專案增大之后,需要說明的地方越來越多,一個README已經太長,使用docusaurus等類似的工具部署一個獨立的檔案站點,

有否自動化版本管理

Why?因為版本號與兼容性是強相關的,具體參考semver規范,

  • 使用husky/yorkie等規范提交日志,
  • 使用standard-version等自動生成CHANGELOG并根據規則自動提升版本號,

最后留個作業

  • 你有什么npm發布時的關鍵經驗這里沒提到的,幫我補充下??
  • 當我們再一次運行npm publish,腦編譯一下,想想這期間都發生了些什么,還少些什么?

作者:京東零售 王凡

內容來源:京東云開發者社區

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/553392.html

標籤:其他

上一篇:現代 CSS 解決方案:CSS 原生支持的三角函式

下一篇:返回列表

標籤雲
其他(159683) Python(38169) JavaScript(25452) Java(18129) C(15231) 區塊鏈(8268) C#(7972) AI(7469) 爪哇(7425) MySQL(7211) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5341) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4576) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2434) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1976) 功能(1967) Web開發(1951) HtmlCss(1944) C++(1922) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1878) .NETCore(1861) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 如何撰寫一個健壯的 npm 包

    比如老王我,用npm init新建一個包,改把改把,然后來個npm publish,so easy ??!Too young too naive, baby ??!請容我講述一些發布程序中踩過的坑。 ......

    uj5u.com 2023-05-25 14:04:45 more
  • 現代 CSS 解決方案:CSS 原生支持的三角函式

    在 CSS 中,存在許多數學函式,這些函式能夠通過簡單的計算操作來生成某些屬性值,例如 : * calc():用于計算任意長度、百分比或數值型資料,并將其作為 CSS 屬性值。 * min() 和 max():用于比較一組數值中的最大值或最小值,也可以與任意長度、百分比或數值型資料一同使用。 * c ......

    uj5u.com 2023-05-25 14:04:28 more
  • 2D 轉換

    1.轉換 轉換(transform)是CSS3中具有顛覆性的特征之一,可以實作元素的位移、旋轉、縮放等效果。 轉換(transform)可以簡單理解為變形。 移動:translate 旋轉:rotate 縮放:scale 1.1 二維坐標系 2D轉換是改變在二維平面上的位置和形狀的一種技術。 1.2 ......

    uj5u.com 2023-05-25 14:04:12 more
  • 【一步步開發AI運動小程式】七、進行運動計時、計數

    > 隨著人工智能技術的不斷發展,阿里體育等IT大廠,推出的“樂動力”、“天天跳繩”AI運動APP,讓**云上運動會、線上運動會、健身打卡、AI體育指導**等概念空前火熱。那么,能否將這些在APP成功應用的場景搬上小程式,分享這些概念的紅利呢?本系列文章就帶您一步一步從零開始開發一個AI運動小程式,本 ......

    uj5u.com 2023-05-25 14:03:53 more
  • 封裝vue基于element的select多選時啟用滑鼠懸停折疊文字以toolti

    相信很多公司的前端開發人員都會選擇使用vue+element-ui的形式來開發公司的管理后臺系統,基于element-ui很豐富的組件生態,我們可以很快速的開發管理后臺系統的頁面(管理后臺系統的頁面也不復雜,大多都是分頁查詢類需求和增刪改查)。但一個前端框架有優點,就必然會有一些缺點或bug存在,e... ......

    uj5u.com 2023-05-25 13:50:15 more
  • 【一步步開發AI運動小程式】七、進行運動計時、計數

    > 隨著人工智能技術的不斷發展,阿里體育等IT大廠,推出的“樂動力”、“天天跳繩”AI運動APP,讓**云上運動會、線上運動會、健身打卡、AI體育指導**等概念空前火熱。那么,能否將這些在APP成功應用的場景搬上小程式,分享這些概念的紅利呢?本系列文章就帶您一步一步從零開始開發一個AI運動小程式,本 ......

    uj5u.com 2023-05-25 13:33:47 more
  • 關于如何處理httpOnly的問題?

    寫這篇的目的是,今天在重新學習javascript時發現了HttpOnly這個標簽,所以專門的mark了下。 誰在什么時候發明了HttpOnly 2002年微軟為ie6的sp1創造了HttpOnly 什么是HttpOnly HttpOnly是包含在http回傳頭Set-Cookie里面的一個附加的f ......

    uj5u.com 2023-05-25 13:32:23 more
  • 關于如何處理httpOnly的問題?

    寫這篇的目的是,今天在重新學習javascript時發現了HttpOnly這個標簽,所以專門的mark了下。 誰在什么時候發明了HttpOnly 2002年微軟為ie6的sp1創造了HttpOnly 什么是HttpOnly HttpOnly是包含在http回傳頭Set-Cookie里面的一個附加的f ......

    uj5u.com 2023-05-25 09:16:50 more
  • Three.js 進階之旅:滾動控制模型影片和相機影片 🦢

    本文將學習如何使用滾動控制 ScrollControls 來控制模型的的影片播放和相機影片,通過滾動滑鼠滾輪或者上下移動觸摸板,來控制模型的影片播放進度或者相機的方位視角,從而呈現出驚艷的視覺效果。通過本文的閱讀和案例頁面的實作,你將學習到的知識包括:R3F 生態中的 ScrollControls、... ......

    uj5u.com 2023-05-25 09:16:10 more
  • Cesium開發案例整理

    >WebGL近幾年越來越被人們所關注,但是二三維開發難度也比普通web要高出許多,不管我們是在在開發或者是學習程序中,往往需要耗費大量的時間去查閱資料,和研究官方案例, >而大多二三維的包(openlayersjs,cesiumjs、threejs)都是外國的,如果英語水平好還行,否則讀起來正是連蒙 ......

    uj5u.com 2023-05-25 09:15:16 more