搭建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 https://npmmirror.com

  • 淘寶鏡像源 https://npmmirror.com
  • 騰訊鏡像源 http://mirrors.cloud.tencent.com/npm/
  • 華為鏡像源 https://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=https://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": [ "https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com", "https://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 配置

官網配置文檔👉 https://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: https://registry.npmjs.org timeout: 10s cache: false yarn: url: https://registry.yarnpkg.com timeout: 10s cache: false npmmirror: url: https://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字段

官方默認配置文件👉 https://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 文件中

https://tool.oschina.net/htpasswd

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

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