私仓选型和搭建

275 阅读8分钟

npm 私有仓库的好处

  1. 安全性角度考虑:如果我们想要一个公共组件库,那么把组件放到我们私有库中,只有内网可以访问,这样可以避免组件中业务的泄露;
  • 2、模块复用性角度考虑:多个项目之间有重复的共有模块,当需要修改模块,通过简单的统一的配置就可以实现;提炼后的组件有专门的地址可以用来查看,方便使用,在后期项目的引用中也能节约开发成本
  • 3、npm 包下载速度角度考虑:使用内部的地址,能够在开发下载 node 包的同时,将关联的依赖包缓存到 npm 私有仓库服务器中,下载速度更快;
  • 4、项目开发中的路劲角度考虑:在项目开发中书写代码更整洁简练,不需书写更长的相对路径;
  • 5、公司技术沉淀角度考虑:知识的沉淀,在公司业务相关的应用上尤佳;
  • 6、版本角度的考虑:相当于一个容器,统一管理需要的包,保持版本的唯一;
  • 7、开发效率角度考虑:使私有公共业务或组件模块能以共有包一样的管理组织方式,保持一致性,提高开发效率

npm 私有仓库的原理

用户 install 后向私有 npm 发起请求,服务器会先查询所请求的这个模块是否是我们自己的私有模块或已经缓存过的公共模块,如果是则直接返回给用户;如果请求的是一个还没有被缓存的公共模块,那么则会向上游源请求模块并进行缓存后返回给用户。上游的源可以是 npm 仓库,也可以是淘宝镜像

npm 私有仓库框架选型

npm 私有仓库搭建有以下几种方式:

  • 付费购买 npm 企业私有仓库,每人每个月7美刀
  • 使用 git + ssh 这种方式直接引用到 GitHub 项目地址
  • 开源代码源代码方式或者 docker 化构建

常用的 npm 私有仓库框架:

Nexus 是 Java 社区的一个方案,可以用于 Maven、npm 多种类型的仓库,适合后端,看到公司有在使用

nexus.ky-tech.com.cn:8081/#browse/sea…

Sinopia 是基于 Node.js 构建的,已经年久失修不维护了,Verdaccio 是 forked Sinopia 进行改造的;Sinopia 和 Verdaccio 比较偏向于一个零配置、轻量型的私有 npm 模块管理工具,不需要额外的数据库配置,它内部自带小型数据库,支持私有模块管理的同时也支持缓存使用过的公共模块,发布及缓存的模块以静态资源形式本地存储。

cnpm 支持静态配置型用户管理机制,以及分层模块权限设置,可以实现公共模块镜像更新以及私有模块管理,支持拓展多种存储形式,相对的数据库的配置较多,部署过程略复杂,是淘宝及多家大型公司搭建内部私有 npm 仓库选择的方案。

基于团队内使用的考虑,使用 Verdaccio 构建成本比较低,后期也好维护,等后面如果需要做完整的 DevOps 流程再详细考虑 Verdaccio 和 cnpm 的优劣。

什么是 Verdaccio?

Verdaccio 是一个 Node.js创建的轻量的私有npm proxy registry

Registry是什么?

  • 包的资源库

  • 提供与 npm clients (yarn/npm/pnpm) 兼容的API

  • Verdaccio 表示意大利中世纪晚期fresco 绘画中流行的一种绿色的意思。

安装

# 必须要加 -g 全局安装
npm install verdaccio -g

安装成功之后随即在命令行输出 verdaccio 随即我们会看到服务已经运行;出现以下内容

根据服务启动后得到两个重要信息

  • verdaccio 配置文件:C:\Users\638692.config\verdaccio\config.yaml
  • verdaccio 默认启动:默认占用 4873 端口

此时访问服务启动地址,就安装完成啦

使用pm2管理verdaccio

npm install pm2 -g
指令描述示例
pm2 -ls列出当前被 pm2 管理的所有进程
pm2 stop <app_namenamespaceid'all'json_conf>关闭某个进程pm2 stop vardaccio
pm2 restart <app_namenamespaceid'all'json_conf>重启某个进程pm2 restart verdaccio
pm2 delete <app_namenamespaceid]'all'json_conf>删除某个进程pm2 delete verdaccio
pm2 start <app_namenamespaceid'all'json_conf>启动某个进程pm2 start verdaccio
pm2 start D:\NVM\v14.16.1\node_modules\verdaccio\bin\verdaccio

verdaccio的配置文件

# This is the default config file. It allows all users to do anything,
# so don't use it on production systems.
#
# Look here for more config file examples: 这个 examples 404了。
# https://github.com/verdaccio/verdaccio/tree/master/conf
#

# 仓库的包默认存储的位置,默认是不存在的,当发布私有包之后会在 /root/.config/verdaccio 中存在
# path to a directory with all packages
storage: ./storage
# path to a directory with plugins to include
plugins: ./plugins

web:
  # 网页 title
  title: Verdaccio
  # comment out to disable gravatar support
  # gravatar: false
  # 包的排序 asc 降序 desc 升序
  # by default packages are ordercer ascendant (asc|desc)
  # sort_packages: asc
  # 是否开启暗黑模式
  # convert your UI to the dark side
  # darkMode: true
  # 网页 logo
  # logo: http://somedomain/somelogo.png
  # 网页 favicon
  # favicon: http://somedomain/favicon.ico | /path/favicon.ico
  # 网页最大连接数
  # rateLimit:
  #   windowMs: 1000
  #   max: 10000

# translate your registry, api i18n not available yet
# i18n:
# 国际化相关,同样404了。
# list of the available translations https://github.com/verdaccio/ui/tree/master/i18n/translations
  # 支持 zh_CN
  #   web: en-US

auth:
  # 注册用户的信息存放位置
  htpasswd:
    file: ./htpasswd
    # Maximum amount of users allowed to register, defaults to "+inf".
    # You can set this to -1 to disable registration.
    # 默认可注册的用户是无限的,如果修改为 -1 则是不允许注册;限定用户方法如下
    # 1,先注册 n 个用户,然后修改配置文件为 -1,后续不允许注册
    # 2,开个 n 个用户注册接口
    # max_users: 1000

# a list of other known repositories we can talk to
# 如果私有库没有的话,去查找以下库。
uplinks:
  npmjs:
    url: https://registry.npmjs.org/

packages:
  # @*/ 是包的作用域 例如 @vue/cli 那么 @vue 则是这个包的作用域,前缀一般都是某个组织或者说某个公司,证明这是个内部包
  '@*/*':
    # scoped packages
    access: $all
    publish: $authenticated
    unpublish: $authenticated
    # 如果私有库没有的话,去 npm 查找查找库。
    proxy: npmjs
  # 普通的 npm 包
  '**':
    # 允许所有用户发布和访问包
    # allow all users (including non-authenticated users) to read and
    # publish all packages
    #
    # 也可以指定指定 @xxx/xxx 类似的作用域
    # you can specify usernames/groupnames (depending on your auth plugin)
    # $all 所有人 $anonymous 只有匿名者可以操作(基本没用) $authenticated 认证用户(通过npm adduser 添加的用户。
    # and three keywords: "$all", "$anonymous", "$authenticated"
    access: $all

    # allow all known users to publish/publish packages
    # (anyone can register by default, remember?)
    publish: $authenticated
    unpublish: $authenticated

     # if package is not available locally, proxy requests to 'npmjs' registry
    proxy: npmjs

# You can specify HTTP/1.1 server keep alive timeout in seconds for incoming connections.
# A value of 0 makes the http server behave similarly to Node.js versions prior to 8.0.0, which did not have a keep-alive timeout.
# WORKAROUND: Through given configuration you can workaround following issue https://github.com/verdaccio/verdaccio/issues/301. Set to 0 in case 60 is not enough.
server:
  keepAliveTimeout: 60

middlewares:
  audit:
    enabled: true

# log settings
logs: { type: stdout, format: pretty, level: http }
#experiments:
#  # support for npm token command
#  token: false
#  # disable writing body size to logs, read more on ticket 1912
#  bytesin_off: false
#  # enable tarball URL redirect for hosting tarball with a different server, the tarball_url_redirect can be a template string
#  tarball_url_redirect: 'https://mycdn.com/verdaccio/${packageName}/${filename}'
#  # the tarball_url_redirect can be a function, takes packageName and filename and returns the url, when working with a js configuration file
#  tarball_url_redirect(packageName, filename) {
#    const signedUrl = // generate a signed url
#    return signedUrl;
#  }

# This affect the web and api (not developed yet)
#i18n:
#web: en-US

listen: 0.0.0.0:4873

nrm 管理 npm 源

nrm 可以很简单的切换多个 npm 原地址。npm, cnpm ... ... 下面简单罗列 nrm 中常用的一些指令。

npm install -g nrm
参数默认值示例描述
lsnrm ls列出所有的源地址
use [source]nrm use cnpm切换到指定的源
add [resigtry] [url]nrm add test http://localhost:8080添加源
del [resigtry]nrm del test删除源

不过一般我们都是在项目上面配置一个.npmrc的文件去指定源

registry=http://localhost:4873/

package.json配置

我们使用了 verdaccio 那就是托管私有仓库,既然是私有仓库,那就尽可能的规范。众所周知 npm 上面包的一些显示信息都是根据 package.json 中的字段名显示的,下面就介绍一些比较关键的内容。

键名示例描述
nametest-comp包的名称,必须。命名规则 @xx/xxxx-xxxxx 尽量使用小写字母
version0.0.1包的版本,必须。版本规则
description这是一个组件库用于添加模块的的描述信息,方便别人了解你的模块。
keywordsui, components, library用于给你的模块添加关键字。当在 npm 中输入内容进行检索的时候回通过 description 和 keywords 中的内容进行检索。
main/index.js项目入口
privatefalse是否是私有库,如果要发布到 npm 修改为 fasle
dependencies{}项目生产环境依赖
devDependencies{}项目开发环境依赖
authorxsq项目作者
licenseMIT开源协议
scriptsnpm run serve启脚本配置
homepagehttp:baidu.com项目主页
bugs{ url: github.com/xxx/issues }bug 地址
repository{ type: git, url: github.com }仓库 地址
files[lib, components, styles]发布到 npm 上面的文件结构,可以尽量使用此配置从而不适用 .npmignore 文件。

发布包&更新已发布包&撤销包

//  首先登录npm 
npm adduser --registry http://localhost:4873/

Username: xxx
Password:  xxx
Email:xxx

//  然后发布包
npm publish --registry http://localhost:4873/

//  删除包
npm unpublish --registry http://localhost:4873/

//  更新指定包
npm update  【pkg】

//  更新版本
npm version [<newversion> | major | minor | patch | premajor | preminor | 
prepatch | prerelease | from-git]

npm publish --registry http://localhost:4873/

major:主版本号(大版本)
minor:次版本号(小更新)
patch:补丁号(补丁)
premajor:预备主版本
preminor: 预备次版本
prepatch:预备补丁版本
prerelease:预发布版本