如何搭建一个私有 npm 服务器

2019 年 5 月 20 日 0 条评论 9.72k 次阅读 10 人点赞

为何需要搭建私有npm仓库?

npm——我们大家都知道是NodeJS的包管理工具,用于Node插件的管理包括安装、卸载、管理依赖等。

基于npm命令行我们可以快速的安装项目中所依赖的代码模块,甚至可以自己发布一些自己写的插件等。使得我们的项目开发效率得到大大的提升。

那么基于npm我们可以做哪些事情呢?

简单来说就是:

  • 一行命令,(批量)安装别人写好的模块
  • 一行命令,卸载安装好的模块
  • 一行命令,更新到最新(或指定版本)的模块

具体在项目里面常用的就是通过npm install ——快速安装项目里package.json里devDependencies和dependencies所依赖的包文件。从而快速启动一个新的项目。

那么问题来了。。。

发布到npm的模块是开源的,我们只能共享大家都能用的开源模块。

然而,现如今随着业务越来越复杂,项目迭代速度也越来越快,那么项目间的常用业务代码共享变得非常之有必要。而对于公司的业务代码我们当然是不能开源的。这时候就需要搭建一个类似于 http://npmjs.org 平台私有的npm仓库,用于企业里面常用的业务模块,如业务组件的存放和快速安装。

通俗一点来说,我们就是要搭建一个属于企业内部的npm仓库,自己管理包的同时借助npm的命令行工具快速复用业务代码模块或者业务组件。
在没有npm私有仓库之前,本着” 避免重复造轮子 “的原则,我们可能是人工的手动去从其他各个项目里面将可以复用的业务代码或业务组件copy过来。

图1 没有NMP私有仓库——人工拷贝业务组件

试想一下我们可能需要做哪些工作?

  • 了解哪些已有项目有我们需要的可复用业务组件
  • 找到项目模块代码并定位组件
  • 详细查看组件代码,考量功能是否契合
  • copy组件到自己的项目

一个组件尚且需要如此大费周折,跟别说多个业务组件。况且由于没有组件的说明文档,每一个组件有可能和自己的需求不是那么契合,而这些关键信息都需要我们花费大量时间去重新阅读代码。

那么你需要的可能就只是——一个的私有npm仓库,有了私有npm仓库之后我们只需输入几行命令那些早已上传到私有仓库的成熟组件就会自动安装到自己的项目里面。

如果人工拷贝需要1-2个小时的话,那么npm私有仓库命令行安装可能只需要1-2分钟。并且私有仓库一般在自己的服务器搭建,更快速稳定。总结来说私有npm仓库有如下好处:

  • 便于管理企业内的业务组件或者模块
  • 私密性
  • 确保npm服务快速、稳定
  • 控制npm模块质量和安全(防止恶意代码植入)

npm及私有npm的工作原理?

在具体了解搭建过程之前,我们先简单了解下npm以及私有npm基本的工作原理。

我们使用npm安装、共享和分发代码,npm帮助我们管理项目中的依赖关系,那么它是如何做到的呢?

具体过程如下图:

图2 npm工作流程示意图
当我们使用npm install去安装一个模块时,会先检查node_modules目录中是否已经存在这个模块,如果没有便会向远程仓库查询。

npm提供了一个模块信息查询服务,通过访问

registry.npmjs.org/packaename/version

就可以查到某个发布在npm模块上的具体信息以及下载地址,下载并解压到本地完成安装。

那如果我们搭建了私有的npm,上述这个过程将如何实现呢?

目前主流的实现方案大致是这样的:

图3 private npm工作流程示意图

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

上游的源可以是npm仓库,也可以是淘宝镜像。

如何搭建一个私有npm仓库?

业界主流的私有npm仓库搭建的主流方案有如下几种:

    1. 付费购买
    2. 使用 git+ssh 这种方式直接引用到 GitHub 项目地址
    3. 使用  verdaccio
    4. 使用 npmjs.org

第一种,一是考虑到公司可能不会提供经费,二npm在国内访问很慢,就是花钱也买不到好的体验。

第二种,不能更新即 npm update, 不能使用semver(语义化版本规范)。

那么较好的选择就只剩下第三种和第四种。

verdaccio 是 sinopia 开源框架的一个fork ,但是由于sinopia 两年前就已经没有人维护了,由于网上搜的都是sinopia,但我实际使用了一波后,坑不要太多,哭死…….. 而且由于没人维护,所有bug ,什么的自己去看源码解决吧, 所以果断弃坑, 找到了这个verdaccio

安装

使用npm 全局安装即可

npm install –g verdaccio

运行

安装完成后直接输入 verdaccio 命令即可运行

这时候我们打开浏览器输入 http://localhost:4873/ 即可打开。如果你不是部署在本机记得要把下面的配置的ip改成0.0.0.0

后面的yaml 是默认的配置文件,4873端口表示默认端口,现在我们可以通过修改默认的配置文件来符合我们的需求.

verdaccio的全部配置

默认配置如下图所示

# #号后面是注释
# 所有包的缓存目录
storage: ./storage
# 插件目录
plugins: ./plugins

#开启web 服务,能够通过web 访问
web:
  # WebUI is enabled as default, if you want disable it, just uncomment this line
  #enable: false
  title: Verdaccio
#验证信息
auth:
  htpasswd:
    #  用户信息存储目录
    file: ./htpasswd
    # Maximum amount of users allowed to register, defaults to "+inf".
    # You can set this to -1 to disable registration.
    #max_users: 1000

# a list of other known repositories we can talk to
#公有仓库配置
uplinks:
  npmjs:
    url: https://registry.npmjs.org/

packages:
  '@*/*':
    # scoped packages
    access: $all
    publish: $authenticated

    #代理 表示没有的仓库会去这个npmjs 里面去找 ,
    #npmjs 又指向  https://registry.npmjs.org/ ,就是上面的 uplinks 配置
    proxy: npmjs

  '**':
    # 三种身份,所有人,匿名用户,认证(登陆)用户
    # "$all", "$anonymous", "$authenticated"

    #是否可访问所需要的权限
    access: $all

    #发布package 的权限
    publish: $authenticated

    # 如果package 不存在,就向代理的上游服务发起请求
    proxy: npmjs

# To use `npm audit` uncomment the following section
middlewares:
  audit:
    enabled: true
# 监听的端口,IP,重点,不配置这个,只能本机能访问
listen: 0.0.0.0:4873
# log settings
logs:
  - {type: stdout, format: pretty, level: http}
  #- {type: file, path: verdaccio.log, level: info}

如何使用
#当前npm 服务指向 本地

npm set registry http://localhost:4873

# 注册用户

npm adduser –registry http://localhost:4873

按照提示输入userName 和 password,email

输入后就注册完成,

#查看当前用户,是否是注册用户.

npm who am i

 

最后一步就是创建一个文件夹,按照npm publish 的标准格式,创建一个私有的package

# 发布包

npm publish

就成功发布了一个私有的包,我们刷新一下,看到包已经出现了。

后续我们就可以在其他模块里面使用 npm install [package name] 来安装了,
而私有npm 里面不包含的包,例如你要安装一个vue ,webpack 这样的包,找不到的话,会被代理到 npm.js 官网去下载,并且会帮你缓存在 ./storage 文件夹里面. 再次下载,就能体验飞一般的速度了,当一个小团队使用的时候效果更佳.

自然如果你还是不喜欢npm ,想用cnpm ,那么可以去修改配置

uplinks:
  npmjs:
    url: https://registry.npmjs.org/

packages:
  '@*/*':
    #npmjs 又指向  https://registry.npmjs.org/ ,就是上面的 uplinks 配置
    proxy: npmjs

#常用的仓库地址
  npm ---- https://registry.npmjs.org/
  cnpm --- http://r.cnpmjs.org/
  taobao - https://registry.npm.taobao.org/
  nj ----- https://registry.nodejitsu.com/
  rednpm - http://registry.mirror.cqupt.edu.cn/
  npmMirror  https://skimdb.npmjs.com/registry/
  edunpm - http://registry.enpmjs.org/

由于考虑到时常会切换仓库来源,我是用了nrm ,一个仓库管理器,实际上就是 简化以下命令
npm set registry [url]

大致上就是如此啦.
如果有错误或者疑惑之处,欢迎留言交流

雷雷

这个人太懒什么东西都没留下

文章评论(0)

(Spamcheck Enabled)