写点什么

分分钟教会你搭建企业级的 npm 私有仓库

2021 年 4 月 01 日

分分钟教会你搭建企业级的 npm 私有仓库

前言


npm 作为一种包管理工具,无论你是泛前端还是大前端都已经离不开它。它的出现方便了万千少年。让我们跨过了 Ctrl+C、Ctrl+V,通过 npm install x 的方式将别人的优秀代码模块引入到自己的项目中。这些优秀的模块能被共享的原因,一方面是有 npm 这么一个包管理工具,另外就是 npm 仓库。


对于 npm 仓库,如果你还停留在使用 npm 或者 cnpm 这类官方源的情况下。那么你有必要想想如何搭建一个私有的 npm 仓库。下面从三个方面讲解企业级 npm 私有仓库搭建那些事儿,分分钟教会你。


  • 为什么需要搭建公司的私有 npm 仓库

  • 如何搭建私有仓库

  • 搭建私有仓库扩展篇


为什么需要搭建公司的私有 npm 仓库


照惯例,先讲讲为啥要搭建私有仓库。目前已经有很多成熟的 npm 源可以使用,比如:


  • npm : https://registry.npmjs.org/

  • cnpm : http://r.cnpmjs.org/

  • taobao: https://registry.npm.taobao.org/

  • nj:https://registry.nodejitsu.com/

  • npmMirror  https://skimdb.npmjs.com/registry/

  • ….


在已经有如此多公共仓库的情况下,是否有必要搞一套私有 仓库?重复"造轮子"?还是自嗨?如果从下面几方面来考虑的话,或许能打消心中的疑问。


1. 稳定性

首先是网络访问稳定性,私有仓库因为是自己公司在维护,有什么问题能第一时间处理,比如服务宕机…其次资源的稳定性,试想一下,如果哪天你依赖的某个很重要的模块突然被作者删了,那是不是完犊子了,毕竟我们很多时候都奉行的是“拿来主义”,一旦遇见这种情况,基本上全抓瞎。如果有私有仓库,上面的问题可以从容面对,有效的保障了业务稳定。


2. 私密性

每个公司都有和自己业务强相关的模块,或者对某些开源模块进行个性化的改造,改造后的模块只满足本公司的业务场景,这些模块我们并不希望发布到公共的仓库中去,这时就可以发布到自己的私有仓库在公司内部共享。


3. 安全性

有了私有仓库后,可以在 npm 模块的质量和安全上做文章,能够有效的防治恶意代码攻击。

综上,搭建自己公司的私有仓库完全有必要,这并不是秀。当然,如果你所在的公司比较 mini,对于上面的几点需求并不是那么迫切,使用公共仓库也挺好。但当公司发展到一定规模,在未来可预见的情况下,那就是时候准备搭建自己的私有仓库了。


如何搭建私有 npm 仓库


目前已经有许多成熟开源方案,选择站在巨人的肩膀上不失为一种良策。这里选择 cnpmjs.org  方案,原因有三:


  1. 目前国内像淘宝这样的大厂内部也是选择的它,足以证明它的可靠性和稳定性

  2. 扩展性强

  3. 配置多样化


当然缺点也不是没有,就是部署有那么一丢丢复杂。


准备工作


兵马未动,粮草先行,既然是搭建企业级的应用,基础环境得备好。


  • Linux 服务器

  • node 环境

  • 数据库( Mysql )

  • nginx


大概就这些,如果你只是熟悉一下,搭着玩儿。也不一定得用 Linux 服务器,Windows 也行,但是如果是作为线上应用,建议还是使用 Linux 服务器,毕竟 Linux 的稳定性在那里摆着。


下面的示例是在云服务器(Ubuntu)上完成的。


安装


安装 cnpmjs.org


建议通过 git 将 cnpmjs.org 的项目源码克隆到服务器本地某个目录下。或者将代码 fork 到自己 git 仓库后,再基于内部仓库进行部署,这样方便以后对源码进行个性化的改造。


git clone https://github.com/cnpm/cnpmjs.org.git
复制代码

安装项目依赖:

npm i
复制代码


安装完成后找到项目根目录下的配置文件 config/index.js ,这里配置文件非常多,刚开始可以只关注下面几项即可,详细配置  戳这里。


  • 服务访问端口

registryPort: 7001,         //仓库服务访问端口webPort: 7002,              //web站点访问端口bindingHost: '',   //监听绑定的 Host,默认127.0.0.1,外网访问注释掉此项即可,一般我们不会把我们内部端口暴露出去,可以在nginx层做一个转
复制代码


  • 数据库配置

database: {  db: 'npm',数据库名称  username: 'admin',//用户  password: 'admin123',//密码  // 数据库类型  // - 目前支持 'mysql', 'sqlite', 'postgres', 'mariadb'  dialect: 'mysql',//默认是sqlite,我选择的mysql  host: '127.0.0.1', //数据库服务地址  port: 3306,    // 端口  // 数据库连接池使用默认配置就好  // 目前只支持  mysql 和 postgresql (since v1.5.0)  pool: {    maxConnections: 10,    minConnections: 0,    maxIdleTime: 30000  },  ...//其他的暂时不用关注},
复制代码


  • 是否启用私有模式

enablePrivate: false,//默认不启用
复制代码


私有模式下,只有管理员才能发布模块。非管理员发布模块式命名必须以 scopes 字段开头例如:@catfly/packagename


  • 发布前缀

scopes: ['@catfly'],
复制代码

这个和启用非私有模式配套使用,非私有模式要发布必须配置该项。


  • 管理员账号配置

admins: {  fengmk2: 'fengmk2@gmail.com',  admin: 'admin@cnpmjs.org',  dead_horse: 'dead_horse@qq.com',}
复制代码

如果启用私有模式,只有该配置项中的用户可以发布私有包。至于其他的配置项暂时不用关注,后面根据需要在逐渐配置起来。


  • 同步模式

// 同步模式选项// none: 不进行同步,只管理用户上传的私有模块,公共模块直接从上游获取// exist: 只同步已经存在于数据库的模块// all: 定时同步所有源registry的模块syncModel:'exist'
复制代码


数据库


我选择的 mysql ,这里不介绍怎么安装 mysql 了,有需要请 戳这里 。当然你也可以选择其他数据库,目前支持 mysql、 sqlite、 postgres、 mariadb,默认是 sqlite。


先检查一下数据库服务状态,确保数据库服务没毛病:



  • 登录数据库

mysql -u root -p test123456
复制代码
  • 创建数据库

create database npm;
复制代码

查看数据库列表:

  • 创建数据库表

    cnpmjs.org 项目 docs 目录下已经给我们备好了创建数据库的脚本 db.sql。执行:

source docs/db.sql;
复制代码

默认当前操作路径就在 cnpmjs.org 项目下,如果不是,请用 db.sql 的绝对路径。

查看结果:

上面两步完成后,就可以将项目跑起来一睹芳容了。因为我们通过 git 克隆的,所以需要进入到项目目录下执行启动服务的命令

npm run start
复制代码

启动成功后,访问 web 页面,发现之前配置文件中的 web 端口 7002 访问不了。


这是因为服务器防火墙的原因,可以选择关闭防火墙,但是这种方式不推荐;另外一种就是开放指定端口。

iptables -A INPUT -p tcp --drop -j 7002 DROP
复制代码

如果你是使用的云服务器,需要去云服务控制台,新增安全组,将暴露的端口放开。

端口开放后,访问 web 页面:xxx.xxx.xxx.xx:7002,就可以看见熟悉的部署在本地的 cnpm 页面了。

在上面这张的访问地址可以看到,用了域名,并不是用的 IP+ 端口的形式,因为作为一个企业级的应用,IP+ 端口的方式就如同裸奔一样,建议采用域名的方式。我在自己的云服务域名管理下新增了一个子域名。

然后配置 nginx 将 IP 和域名进行绑定,统一使用默认的 80 端口,尽量不要将私有仓库服务的真实端口和 IP 暴露出来。这里顺便把 nginx 配置也说一下,如果你能接受 IP+ 端口访问的方式,可以跳过下面这一步。


nginx 配置


如果没有安装 nginx,戳这里 (https://www.runoob.com/linux/nginx-install-setup.html)。找到 nginx 配置文件,在 conf.d 文件夹信息新增 npm.conf 配置文件,这样功能清楚明白,因为很多时候 nginx 不是只代理这个一个服务。


server {  listen  80;  server_name www.mirrors.catfly.vip;  #charset koi8-r;  #access_log  logs/host.access.log  main;  location / {     proxy_pass http://127.0.0.1:7002/; #代理到cnpmjs.org提供的web服务    proxy_set_header        X-Real-IP $remote_addr;  }  location /registry/ {    proxy_pass http://127.0.0.1:7001/; # 代理到cnpmjs.org提供的注册服务    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header Host $host;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  }  #error_page  404              /404.html;  # redirect server error pages to the static page /50x.html  # error_page   500 502 503 504  /50x.html;  location = /50x.html {    root   html;  }}
复制代码

重启 nginx:

service nginx restart
复制代码

检查 nginx 状态,防止配置错误,导致重启失败。

通过上面的环境搭建和部署,基本工作就完成了,下面开始验证功能。


功能验证


在验证之前推荐安装一个 npm 源管理模块 nrm ,有了它我们可以在各种源之间自由切换。

npm i nrm -g
复制代码

安装成功后新增我们自己的私有源到 nrm 源列表中。

nrm add catfly http://www.mirrors.catfly.vip/registry
复制代码

切换到私有源:

nrm use catfly
复制代码



这个时候本地执行 npm 操作的时候就会去找到我们自己的私有地址。


  1. 私有包发布


注册用户:

npm adduser
复制代码


登录私有仓库:

npm login
复制代码


登录成功后,发布 npm,在已准备好的模块目录执行:


npm publish
复制代码


这个时候可能会出现各种错误,主要是 403 权限问题,因为私有仓库在不同模式下需要满足不同的条件,例如:

  • 在非私有模式(enablePrivate: false)下,当用户不用具备管理员权限,模块命名前缀必须带有配置中规定的 scope,如果不存在或者 scopes 中不包含该 scope 就会报错。

  • 在私有模式(enablePrivate: true)下,如果用户不在配置文件的 admins 中,则不允许执行发布操作,反过来如果在,那么他的权限就非常大了,不仅能发布还能删除。所以真实场景下不要让管理员账号泛滥。


  1. 包下载安装


发布成功后,尝试安装发布的私有包:

npm i xxxxx
复制代码

没毛病。


  1. Web 工作台


访问私有仓库的 web 站点

通过这个 站点可以对私有包的发布、删除以及下载进行统计,还可以私有包搜索功能。也可以对这个 web 站点进行个性化改造。代码、数据都在我们这边,想怎么造就怎么造。



头图:Unsplash

作者:小飞猫

原文:https://mp.weixin.qq.com/s/Q9JSBXx7eiq3GuAvg1itIw

原文:分分钟教会你搭建企业级的 npm 私有仓库

来源:政采云前端团队 - 微信公众号 [ID:Zoo-Team]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2021 年 4 月 01 日 13:041861

评论

发布
暂无评论
发现更多内容

云图说 | 华为云应用服务网格,让你的应用治理智能化、可视化

华为云开发者社区

网络I

Redis 发布订阅,小功能大用处,真没那么废材!

楼下小黑哥

Java redis spring

超越色彩的魅力:读《黑白适界》

北风

艺术 摄影 黑白 摄影征文 画册

解Bug之路-记一次对端机器宕机后的tcp行为

无毁的湖光

Linux TCP socket MQ Java 分布式

高难度对话读书笔记—情绪篇2

wo是一棵草

记一次"截图"功能的项目调研过程!

云流

编程开发 程序员代码 项目实战 架构师技能

快速了解前端开发HTML的正确姿势

华为云开发者社区

CSS html

架构师训练营第二周学习总结

邓昀垚

Java多线程知识点总结(思维导图+源码笔记),已整理成PDF版文档

Java架构之路

Java 程序员 面试 编程语言 多线程

九、给小白看的第二篇Python基础教程

刘润森

Python

架构师训练营第二周作业

邓昀垚

微前端qiankun从搭建到部署的实践

fengxianqi

前端框架 微前端 微应用

看动画学算法之:排序-count排序

程序那些事

动画 看动画学算法 看动画学数据结构 count排序

第6周作业

方堃

anyRTC无人机图传方案

anyRTC开发者

WebRTC 语音 直播 RTC 安卓

从基础到实践,一文带你看懂HashMap

华为云开发者社区

Java hashmap

一分钟带你认识深度学习中的知识蒸馏

华为云开发者社区

学习

一大波人气博主袭来,现场直播华为全联接2020!

华为云开发者社区

开发者 华为云

第7周的总结

Vincent

极客时间 极客大学

译文|简明指南:Apache Pulsar 的分层存储

Apache Pulsar

开源 云原生 存储分离 Apache Pulsar 消息中间件

是的,我去封闭开发了

lockdown56

生活,随想 工作哲学 摄影 摄影征文

架构师第一期作业(第二周)

Cheer

课程作业

腾讯这份Java面试核心,开源半天就收到Git近10W点赞

小Q

Java 分布式 算法 JVM 多线程

可以秒杀全场的SpringCloud微服务电商实战项目,文档贼全

Java架构之路

Java 程序员 编程语言 架构师 项目实战

响应式编程到底是什么?

博文视点Broadview

Java 响应式 响应式编程 reactor 并发

第2周

Geek_fabd84

Spring知识点总结!已整理成142页离线文档(源码笔记+思维导图)

Java架构之路

Java spring 程序员 面试 编程语言

网站审核提不了款维护的解决方法有哪些?

丛林里的余光

网站平台

学习编程

InfoQ_34a83d636158

oeasy 教您玩转 linux 010400 总结 summary

o

Android Native crash处理案例分享

阿里云金融线TAM SRE专家服务团队

android

4月17日 HarmonyOS 开发者日·上海站

4月17日 HarmonyOS 开发者日·上海站

分分钟教会你搭建企业级的 npm 私有仓库-InfoQ