搭建npm私服,我為什麼推薦Verdaccio?

語言: CN / TW / HK

highlight: atom-one-dark theme: vuepress


我正在參加「掘金·啟航計劃」

1. npm私服是什麼

在自己的伺服器上部署一個支援釋出、下載、版本管理等服務的npm倉庫就是npm私服,也叫私有化部署npm

540px-Npm-logo.svg.png

眾所周知的原因,國內下載npm包特別慢甚至下載失敗,所以安裝完node.js還要設定映象源,映象源就屬於私服的一種

映象源:是以一定頻率定時同步npm官方倉庫,以此代替官方倉庫,提高包下載速度

shell npm config set registry http://npmmirror.com

  • 淘寶映象源 http://npmmirror.com
  • 騰訊映象源 http://mirrors.cloud.tencent.com/npm/
  • 華為映象源 http://mirrors.huaweicloud.com/repository/npm/

有了映象源為什麼還需要npm私服?

可達鴨sikao.png

映象源解決了國內下載速度的問題,但是不能發包

如果公司有自己的元件庫,又不希望在網上公開,如何管理程式碼?

在每個專案裡複製一遍,但是當元件修改了程式碼,就需要重新複製一遍, 帶來的維護成本太高

這時就需要npm私服

2. npm私服有什麼用

2.1 釋出私有包

私服最重要的功能就是釋出私有包,既能保證程式碼不公開又能享受npm安裝的快捷

舉個栗子🌰

在開發中通常會把一些方法封裝成 utils.js,在專案初始化時複製一份

有了私服後就可以發一個 myUtils 包,然後通過 npm install myUtils 來安裝

通過修改版本號就能快速更新包

ps:把專案模板發一個包,媽媽再也不用擔心專案初始化了😁

跳動.gif

2.2 連結npm倉庫

在一個專案中使用多個倉庫下載包時,可以配置 .npmrc 指定下載地址

舉個栗子🌰

vue 包從淘寶映象源下載

myUtils 包從私服下載

.npmrc 需要配置兩個包的下載地址,還要在 package.json 中將私有包 myUtils 加上組織名 @sf/myUtils

```shell

淘寶映象源

registry=http://npmmirror.com

私有源

@sf:registry=http://... ```

甚至...

隔壁專案組也有自己的倉庫,你又要用到他們的包,只好再次修改 .npmrc

image-20220809212700003.png

更好的辦法

使用私服的倉庫連結功能(上行鏈路),就可以把多個倉庫聚合成一個下載入口

上面的例子 .npmrc 只需要配置一個私服的地址 registry=http://...

省事省力

聚合.png

2.3 提高下載速度

通過私服下載的包會快取到伺服器中

下載同一個包(同組織/名/版本)時優先從快取中讀取,找不到再從映象或官方倉庫下載

快取策略可配置儲存空間大小,儲存週期等

3. 私服方案

3.1 開源免費

| 方案 | 支援倉庫 | star數 | github | 開發語言 | 更新頻率 | | ------------ | --------------------------- | ------ | -------------------------------------------------------- | ---------- | -------- | | Nexus 開源版 | maven,npm,docker,pypi... | 1.2k | nexus-public | Java | 高 | | Sinopia | npm | 5.5k | sinopia | JavaScript | 停止更新 | | Verdaccio | npm | 13.7k | verdaccio | JavaScript | 高 | | cnpm.org | npm | 3.6k | cnpmjs.org | JavaScript | 停止更新 | | cnpmcore | npm | < 500 | cnpmcore | TypeScript | 高 |

看起來是5個專案,其實是3個

Sinopia 停止更新後,社群大佬fork了一份並更名為 Verdaccio

cnpm.org 停止更新後,團隊使用 TypeScript 重構並新建了 cnpmcore 倉庫,目前 star數並不高

資料截至到2022年08月10日

所以可選的開源方案並不多,目前最受社群歡迎的就 VerdaccioNexus 兩個

倆logo.png

3.2 收費方案

JFrog Artifactory 號稱是 "最好的通用儲存庫管理器",支援 docker、npm、maven、pypi等50多種倉庫

官網

4. 為什麼推薦Verdaccio

verdaccio 6 已經在開發中,注意關注動態

很多團隊使用 Nexus ,原因是 Nexus 同時支援 Maven、npm 倉庫

同時支援前後端的倉庫,為了省事就不再單獨部署 npm 倉庫

從npm命令的角度二者差異不大,支援npm的多數命令,那為什麼推薦 Verdaccio 呢?

4.1 npm命令

截止到 5.15.3 版 Verdaccio 支援以下npm命令

| 功能 | 命令 | 是否支援 | | -------- | ------------------------------- | -------- | | 安裝包 | npm install、npm upgrade | ✅ | | 釋出包 | npm publish | ✅ | | 取消釋出 | npm unpublish | ✅ | | 標記 | npm tag | ✅ | | 棄用 | npm deprecate | ✅ | | 註冊使用者 | npm adduser {newuser} | ✅ | | 令牌 | npm token | ✅ | | 轉讓包 | | ❌ | | 搜尋 | npm search | ✅ | | ping | npm ping | ✅ | | 加星 | npm star、npm unstar、npm stars | ✅ | | 審計 | npm audit | ✅ |

4.2 理由1

三個系統.png

二者最大的差異在於 Web 介面上

Verdaccio 顯示了包名、描述、作者、版本、標籤、更新時間、協議等資訊,更接近npm官方介面

Nexus 上的資訊則少的多

這是因為 Nexus 是一款綜合倉庫管理系統,不僅支援 npm,還有 maven,pypi 等倉庫,對包的資訊處理就沒有 Verdaccio 直觀

為什麼Web介面很重要?

講一下親身經歷,剛來公司時不知道發了哪些包,包的用途

只能從 Nexus 上扒拉,再去git檢視 README,程式碼

給後繼者帶來極大不便😣

image-20220811154856782.png

所以易用的 npm 倉庫能方便快速瞭解團隊專案,提高開發效率。尤其開發人員變動時,感觸尤為深刻

看個動圖感受一下 Verdaccio 的介面

Verdaccio詳情.gif

Verdaccio

  • 提供各類包管理器 npm yarn pnpm 的安裝命令,一鍵複製

  • 直接將 README.md 渲染到頁面上,不用再去git上翻 README

ps:變相督促大家好好寫 README 🤣

  • 檢視依賴包,點選跳轉到對應包的詳情頁

  • 歷史版本

  • 上行鏈路,這就是前面說的 連結npm 倉庫 (圖中沒有配置 UPLINKS)

  • 右上角包括倉庫資訊、登入,還有夜間模式等

Nexus詳情.gif

Nexus

Nexus 需要先選版本再檢視詳情

npm包資訊內容與 Verdaccio 不同,展現形式也完全不一樣

Nexus 像一個 “字典”,把所有重要資訊羅列給你,Verdaccio 像一個 “工具” ,用起來更順手

4.3 理由2

除了有好看的皮囊,在其他方面 Verdaccio 也是一點不差

image-20220812205249597.png

安裝簡單

支援 npm 、Docker 映象、Helm Chart、Cloudron 多種安裝方式,一行命令即可安裝

身份驗證

內建賬號註冊,登入功能(預設使用htpasswd),可通過外掛擴充套件LDAP等驗證方式

許可權控制

根據需要允許和限制對某個包的訪問、下載

上行鏈路

支援多個關聯多個npm倉庫

Webhooks

通過npm publish 釋出包時,可傳送通知

日誌

詳細的日誌記錄

外掛支援

官方支援認證、中介軟體、儲存、主題,4種類型外掛,可根據需求自己開發外掛,官網提供了詳細的開發文件

5. 從零開始搭建

從隔壁小黑那借來一臺 CentOS 7,開淦

官方提供了 docker 映象,為了省事直接使用 docker 安裝

5.1 安裝docker

使用 yum-utils 管理 yum 倉庫

```shell

安裝yum-utils

yum install -y yum-utils ```

新增 docker 的 yum 源

```shell

新增docker-ce源

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新yum快取

yum --enablerepo=updates clean metadata ```

安裝 docker docker-compose 並執行

```shell

安裝

yum -y install docker-ce docker-ce-cli docker-compose

啟動

systemctl enable docker && systemctl start docker ```

Snipaste_2022-10-09_19-42-47.png

5.2 配置docker映象源

已經配置過的直接下一步

```shell

docker配置資料夾

mkdir /etc/docker

編輯配置檔案

vi /etc/docker/daemon.json ```

修改 registry-mirrors 和 dns 配置

json { "registry-mirrors": [ "http://docker.mirrors.ustc.edu.cn", "http://hub-mirror.c.163.com", "http://reg-mirror.qiniu.com" ], "dns": ["114.114.114.114","8.8.8.8"] }

重啟docker

```shell

重啟配置

systemctl daemon-reload

重啟docker

systemctl restart docker ```

Snipaste_2022-10-09_19-44-20.png

5.3 Verdaccio 容器配置

本文以安裝到 /verdaccio 目錄為例

安裝共需要3個檔案

  • docker-compose.yaml docker容器配置
  • config.yaml verdaccio配置檔案
  • htpasswd 使用者密碼檔案

```shell

目錄結構

└── /verdaccio 專案目錄 ├──/conf 配置目錄 │ └── config.yaml verdaccio 配置檔案 │ └── htpasswd 使用者密碼檔案 │ ├──/storage 包存放目錄 │ ├──/plugins 外掛目錄 │ └── docker-compose.yaml docker-compose 配置檔案 ```

Snipaste_2022-10-09_19-45-52.png

  1. 首先建立 docker-compose.yaml 檔案

docker-compose 是定義和執行docker容器的工具,通過 .yaml 檔案配置容器

```shell

建立目錄

mkdir /verdaccio

建立yaml檔案

touch /verdaccio/docker-compose.yaml

```

  1. 修改容器配置

```shell

用vi編輯器開啟檔案

vi /verdaccio/docker-compose.yaml ```

輸入以下內容

```yaml version: '3.1'

services: verdaccio: image: verdaccio/verdaccio container_name: "verdaccio" networks: - node-network environment: - VERDACCIO_PORT=4873 ports: - "4873:4873" volumes: - "./storage:/verdaccio/storage" - "./conf:/verdaccio/conf" - "./plugins:/verdaccio/plugins" networks: node-network: driver: bridge ```

  • version:docker對應版本號 (構建時出錯請改小一點版本號)
  • image:verdccio映象
  • 三個 4873 是verdaccio訪問埠號
  • volumes:是掛載物理機的目錄到 docker 中
  • 第一行:儲存目錄,用於儲存npm包
  • 第二行:配置檔案目錄,下一節 Verdaccio 配置 會講解
  • 第三行:外掛目錄

本地建立好 docker-compose.yaml 傳到 CentOS 也是極好的

Snipaste_2022-09-27_20-34-43.png

5.4 Verdaccio 配置

官網配置文件👉 http://verdaccio.org/zh-cn/docs/configuration/

  1. 建立配置檔案 config.yaml

Verdaccio 的配置檔案,上行鏈路、外掛、密碼檔案位置等等引數都通過 config.yaml 配置

```shell

建立目錄

mkdir /verdaccio/conf

建立檔案

touch /verdaccio/conf/config.yaml ```

  1. 修改配置

```shell

用vi編輯器開啟檔案

vi /verdaccio/conf/config.yaml ```

輸入以下內容

```yaml

npm包快取目錄

storage: /verdaccio/storage

外掛目錄

plugins: /verdaccio/plugins

密碼檔案

auth: htpasswd: file: /verdaccio/conf/htpasswd

上行鏈路

uplinks: npmjs: url: http://registry.npmjs.org timeout: 10s cache: false yarn: url: http://registry.yarnpkg.com timeout: 10s cache: false npmmirror: url: http://registry.npmmirror.com packages: # 帶@的包只能登入後釋出 "@/": # 訪問包的許可權 access: $all # 釋出包的許可權 publish: $authenticated # 代理鏈 proxy: npmjs npmmirror yarn # 普通包所有人都能釋出 "**": access: $all publish: $all proxy: npmjs npmmirror yarn middlewares: # 啟用 npm audit audit: enabled: true logs: - { type: stdout, format: pretty, level: http }

監聽埠

listen: 0.0.0.0:4873 ```

在 packages 中共有三種使用者角色

| 角色 | 描述 | | -------------- | ---------- | | $all | 所有使用者 | | $anonymous | 匿名使用者 | | $authenticated | 登入的使用者 |

在packages中可以定義某個包的釋出下載規則

網站的標題、Logo等設定參考 github web欄位

官方預設配置檔案👉 http://github.com/verdaccio/verdaccio/blob/5.x/conf/default.yaml

5.5 建立容器並啟動

執行以下命令

```shell

進入verdaccio目錄

cd /verdaccio

構建

docker-compose up --build ```

Snipaste_2022-10-09_19-47-39.png

看到這樣的提示後就可以開啟瀏覽器訪問verdaccio了

此時docker執行在前臺,Ctrl + C 結束命令就無法訪問

Snipaste_2022-10-09_19-49-20.png

5.6 啟動和停止

編譯通過一次後,下次直接用 docker run 命令啟動,不需要再編譯 -d 是在後臺執行的意思

啟動

shell docker run -d verdaccio/verdaccio

Snipaste_2022-10-09_19-56-23.png

停止

```shell

檢視執行中的容器

docker ps -a

找到pid (CONTAINER ID)

docker stop * ```

image-20221009195902497.png

💥 如果出現啟動以後無法訪問,需要升級核心之後重啟

shell yum update

6. 使用Verdaccio

詳細命令參考 4.1 npm命令

把私服地址 配置到專案的 .npmrc 即可

js registry=http://你的地址:4873/

註冊使用者

shell npm adduser --registry http://你的地址:4873/

釋出包

shell npm publish --registry http://你的地址:4873/

verdaccio 設定

```shell

已經做過docker的對映,只需修改 /verdaccio/conf/config.yaml

```

最重要的可以通過網頁瀏覽 npm 包

密碼管理

verdaccio使用 htpasswd 格式管理密碼,可以用工具生成,貼上到 /verdaccio/conf/htpasswd 檔案中

http://tool.oschina.net/htpasswd

在寫作過程中參考過以下內容

http://segmentfault.com/a/1190000020684605 http://blog.csdn.net/liuhangbiao/article/details/117604766