zxsby / blog

3 stars 0 forks source link

npm私服搭建 #4

Open zxsby opened 3 years ago

zxsby commented 3 years ago

nrm

nrm 是一个npm源管理器,允许你快速在npm源之间进行切换。

npm install -g nrm  //安装nrm
nrm ls //查看可选源(带*号的为当前源)
nrm current //查看当前使用源
nrm use <registry>  //registry为源名  比如切换taobao源
nrm add <registry> <url>   //registry为源名  url为源地址
nrm del <registry>  //registry为源名,删除某个源,比如删除刚刚的company
nrm test <registry>  //registry为源名,测试源的响应时间
zxsby commented 3 years ago

npm私有库---verdaccio

verdaccion官方网址

verdaccion安装

verdaccio安装方式有几种,文档资料:https://verdaccio.org/docs/zh-CN/installation,在这里我使用的是npm下载verdaccio的方式。

//在cmd输入
npm install -g verdaccio  //npm下载

yarn global add verdaccio  //yarn下载  用yarn下载的时候 verdaccio运行不起来的时候请换成npm下载

//或者nrm切换下源地址  要是报权限错误的话,请选择cmd<以管理员身份运行>在输入一次
//或者在cmd输入下面的命令:
npm install -g verdaccio --unsafe-perm
//--unsafe-perm添加上是为了防止报 gyp ERR! permission denied 的权限问题

//下载完成后会有红色字体表示:表示没有python的环境,这个时候不需要理会。

//在cmd输入:verdaccio 执行效果如下:

img

默认端口号是4873,在谷歌浏览器显示页面是:

配置信息

在上面的图片可以得到verdaccio文件的配置文件地址:C:\Users\账户\AppData\Roaming\verdaccio,可以看到文件如图所示:

默认启动服务需要占用4873端口,若启动verdaccio服务失败请检查该端口是否被占用,或者手动修改对应的配置文件。配置文件在上图能找出,修改其端口号。

config.yaml文件配置信息:https://verdaccio.org/docs/en/configuration

  #
  # 这是默认的配置文件. 它会允许我们做任何事情,
  # 所以不要在生产环境(系统)使用它.
  #
  # 在这里可以看见更多的配置示例:
  # https://github.com/verdaccio/verdaccio/tree/master/conf
  #

  # 包含所有包的目录路径,npm私服包的存放目录以及缓存地址
  storage: ./storage
  # 包含plugins的目录路径,默认插件的文件位置,一般只对docker部署有关系
  plugins: ./plugins

  web:  #verdaccio的界面
    title: Verdaccio
    # comment out to disable gravatar support 注释掉gravatar禁止使用
    # gravatar: false
    # by default packages are ordercer ascendant (asc|desc)  默认的packages是准备好的两个选择
    # sort_packages: asc
    # convert your UI to the dark side  用户界面是黑夜模式
    # darkMode: true

  # translate your registry, api i18n not available yet  看看下你的注册表,i18n api还不能使用
  # i18n:
  # list of the available translations 查看可以使用的注册列表的地址:https://github.com/verdaccio/ui/tree/master/i18n/translations
  #   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去禁止用户通过 npm adduser 去注册
      # max_users: 1000  #默认注册人数最大数量是1000

  # a list of other known repositories we can talk to  我们需要了解其他相关有名的存储库
  uplinks: #配置上游的npm服务器,主要用于请求的库不存在时可以去到上游服务器去获取,可以多配置下上游链路的链接
    npmjs:
      url: https://registry.npmjs.org/
      agent_options:  #代理的配置项
        keepAlive: true
        maxSockets: 40
        maxFreeSockets: 10

  packages: # 配置模块,access访问下载权限,pushlish包的发布权限
    '@*/*': # 一种是@/表示某下面所属的某项目,关键字匹配
      # scoped packages   配置权限管理
      access: $all # 表示哪一类用户可以对匹配的项目进行安装(install)和查看包的信息
      publish: $authenticated # 表示哪一类用户可以对匹配的项目进行发布(publish)
      unpublish: $authenticated # 表示哪一类用户可以对匹配的项目进行卸载(publish)
      proxy: npmjs # 这里的值是对应于 uplinks 的名称,如果本地不存在,允许去对应的uplinks去拉取

    '**': # 另一种是*匹配项目名称(名称在package.json中有定义)
      # allow all users (including non-authenticated users) to read and
      # publish all packages
      # 允许所有用户(包括未经身份验证的用户)读取和发布所有包
      # you can specify usernames/groupnames (depending on your auth plugin) 您可以指定用户名/组织名称(取决于验证身份的插件)
      # and three keywords: "$all", "$anonymous", "$authenticated" 三个关键字:所有的,匿名的,验证过的  也可以使用具体的用户名或者组织名称(公司私有的名字)和配置的用户表 htpasswd 有关
      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注册表的代理
      proxy: npmjs

  # You can specify HTTP/1.1 server keep alive timeout in seconds for incoming connections. 传入的指定连接的HTTP/1.1服务器保持活跃状态直到超时,以秒为单位
  # 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.  值为0的时候的服务表现行为和8.0.0之前版本的nodejs链接的时候没有保持活跃状态导致超时
  # 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.  如果60不够的话可以设置为0
  server:
    keepAliveTimeout: 60

  middlewares:
    audit:
      enabled: true

  # log settings  设置日志
  logs:
    - { type: stdout, format: pretty, level: http }
    #- {type: file, path: verdaccio.log, level: info}
  #experiments: 实验性的
  #  # support for npm token command  支持npm的token令牌
  #  token: false
  #  # support for the new v1 search endpoint, functional by incomplete read more on ticket 1732
  #  search: false
  #  # disable writing body size to logs, read more on ticket 1912
  #  bytesin_off: false

  # This affect the web and api (not developed yet) 这些会影响web和api(尚未开发的功能)
  #i18n:
  #web: en-US

  #默认是没有的,只能在本机访问,添加后可以通过外网访问
  listen:0.0.0.0:4873

通过pm2启动verdaccio

✨pm2 是一款著名的nodejs进程守护和管理工具

  npm install -g pm2 //安装pm2

  pm2 start verdaccio //启动verdaccio  status为online即为成功 如下图所示:

pm2 常见的执行命令:

  npm install pm2 -g     // 命令行安装 pm2
  pm2 start app.js       // 启动app.js应用程序
  pm2 start app.js -i 4  // 后台运行pm2,启动4个app.js
                          // 也可以把'max' 参数传递给 star
                          // 正确的进程数目依赖于Cpu的核心数目
  pm2 start app.js  --watch      // 当文件变化时自动重启应用
  pm2 list                       // 列表 PM2 启动的所有的应用程序
  pm2 monit                      // 显示每个应用程序的CPU和内存占用情况
  pm2 logs                       // 显示所有进程日志
  pm2 start app.js --name="api"  // 启动应用程序并命名为 "api"
  pm2 start script.sh            // 启动 bash 脚本
  pm2 show [app-name]            // 显示应用程序的所有信息
  pm2 logs [app-name]            // 显示指定应用程序的日志
  pm2 stop all                   // 停止所有的应用程序
  pm2 stop 0                     // 停止 id为 0的指定应用程序
  pm2 restart all                // 重启所有应用
  pm2 restart 0                  // 重启指定的进程
  pm2 delete all                 // 关闭并删除所有应用
  pm2 delete 0                   // 删除指定应用程序id为0的

npm包的流程

新建一个文件夹名称为npm-test ,在cmd控制台上输入

  cd npm-test

  npm init        //初始化   默认指向index.js文件,所以新建一个index.js文件
//index.js文件
module.exports.Say = function(name){
    return  ("Hello " + name);
}

简单写完之后可以发布包啦!前提是cmd启动verdaccio才可以的。

npm adduser --registry http://localhost:4873      //添加功能,无账号的添加完毕直接包

npm login --registry=http://localhost:4873        //登录功能,有账号的话可以直接使用这个

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

输入自己的用户名,密码,邮箱地址,成功结果如上图所示。

发布成功如上图所示。小小提示下可以使用nrm进行管理npm源,来避免手动输入registry

nrm add company http://localhost:4873  //company可以换任意名称  url地址  添加功能
nrm use company       //使用company的源地址

//这样的话简单了结,不用手动输入registry
npm addUser
npm login
npm publish

//注意:registry要切换到公司私有服务器地址,如果不是用nrm管理切换,则需要带上私有registry(重复啦!)

此时在http://localhost:4873/ 页面上进行更新,就会发现你发布的包(包的名称就是文件的名称)。

我们来下载刚刚发布的包

//注意:registry要切换到公司私有服务器地址,如果不是用nrm管理切换,则需要带上私有registry(再来一遍)
//新建一个文件夹名为  app
cd app
npm install npm-test  //要是没有切换的话,请手动添加 --registry=http://localhost:4873
//成功如图所示

删除发布的包

npm unpublish npm-test --force  //清除发布的包

其他知识点

npm私有库的权限管理

因为verdaccio默认是人人都可以注册的,所以需要先将注册窗口关闭

auth:
  htpasswd:
    file: ./htpasswd
    // 此配置项可以关闭注册功能
    max_users: -1

verdaccio 的认证是基于verdaccio-htpasswd, 可以通过官方提供的工具来生成

http://www.htaccesstools.com/htpasswd-generator/,将生成的段字符串添加到htpasswd中即可,这样的话就可以登录npm私有库

之后就需要修改verdaccio文件下的config.yaml的配置:针对不同的包来设置access,publish,unpublish对应的权限组,因为htpasswd是默认的鉴权插件,所以只能写入相应的用户名,all,authenticated,$anonymous

//小小实例下:
auth:
  htpasswd:
    file: ./htpasswd
    // 此配置项可以关闭注册功能
    max_users: -1
    duGroup:
    // 这里可以自定义用户组
    demoPublish: [xiaoming, xiaohong, xiaoli]
    demoUnpublish: [xiaojun, xiaoming]
    testPublish: [xiaoming,xiaojun]

 packages:
        '@demo/*':
            access: $all
        // 针对不同的包,可以指定不同的用户组来满足权限控制
            publish: demoPublish
            unpublish: demoUnpublish
            proxy: npmjs
     'test':
            access: $all
            publish: testPublish
            unpublish: demoUnpublish
            proxy: npmjs

或者通过安装htpasswd-for-sinopia工具来添加账号

 npm install htpasswd-for-sinopia -g

 sinopia-adduser   // 在 htpasswd 目录执行

为其他登录的用户生成用户名和密码,之后将用户名和密码写入verdaccio文件夹下的htpasswd文件中,然后就跟上文是一样的步骤。

zxsby commented 3 years ago

npm私有库--Cnpmjs.org

Cnpmjs.org的流程

github的地址

//安装cnpmjs.org  建议克隆源码,针对公司内部进行个性化改造
git clone https://github.com/cnpm/cnpmjs.org.git

//安装项目依赖   cd cnpmjs.org
npm install

安装完后,在项目的根目录下找配置文件 config/index.js ,这里面的信息量很多,我们只需要关注下几项就可以啦,详细配置的地址

/*
 * server configure //服务器配置
 */

registryPort: 7001,         //仓库访问端口(执行发布安装)
webPort: 7002,              //展示查询站点访问端口
bindingHost: '',            //监听绑定的 Host,默认127.0.0.1,外网访问注释掉此项即可

/**
* database config           //数据库相关设置
*/

database: {
    db: 'cnpmjs',           //数据库名称
    username: 'root',       //数据库访问账号
    password: '123456',     //数据库访问密码

    // the sql dialect of the database  数据库支持的类型
    // - currently supported: 'mysql', 'sqlite', 'postgres', 'mariadb'
    dialect: 'mysql',       //使用数据库,默认sqlite,这里我们改成mysql

    // custom host; default: 127.0.0.1
    host: '127.0.0.1',      //数据库访问IP,通常127.0.0.1

    // custom port; default: 3306
    port: 3306,             //数据库访问端口,通常3306

  // 数据库连接池使用默认配置就好
  // 目前只支持  mysql 和 postgresql (since v1.5.0)
  pool: {
    maxConnections: 10,
    minConnections: 0,
    maxIdleTime: 30000
//...

// 模块文件存储,默认将发布的私有模块跟缓存公共模块存储在本地文件系统中,路径~/.cnpmjs.org/nfs ,也就是模块文件都存储在这个目录下;或者可以选择三方储存方式比如七牛等,着这里配置插件;也支持接口开发扩展储存;

nfs: require('fs-cnpm')({
    dir: path.join(dataDir, 'nfs')
}),

// registry url name        //模块注册列表访问域名,默认r.cnpmjs.org,安装模块时会到这个域名下查找,这个默认设置略坑,建议没有外网域名的先清空回头再配
registryHost: '',

// default system admins    //默认管理员账号
  admins: {
    // name: email
    //fengmk2: 'fengmk2@gmail.com',
    admin: 'admin@cnpmjs.org',
    //dead_horse: 'dead_horse@qq.com',
  },

/*
 * registry mode config  私有模块发布相关配置
*/

  //是否开启私有模式,默认为 false;
  //私有模式下只有管理员能发布模块,其他账号只有同步权限
  //非私有模式,注册用户都可以发布模块
  enablePrivate: false,

  // registry scopes
  //若为非私有模式发布则此项必填,非管理员发布模块式命名必须以scopes字段开头,模块命名示例“@cnpm/packagename”
  //更多了解npm-scope请查阅https://docs.npmjs.com/misc/scope
  scopes: [ '@cnpm', '@cnpmtest', '@cnpm-test' ],

  // 私有模块非scopes白名单,各种非以scope方式发布的老模块的白名单管理,数组形式维护
  privatePackages: [],

/**
* sync configs 同步源仓库相关设置
*/

//npm官方registry地址,不会直接从这个地址同步模块,但有时会从这里获取模块信息,除非必要请勿更改
officialNpmRegistry: 'https://registry.npmjs.com',
officialNpmReplicate: 'https://replicate.npmjs.com',

//同步模块上游registry地址
sourceNpmRegistry: 'https://registry.npm.taobao.org',

//上游registry是否是cnpm,默认true,若要使用npm官方地址作为同步上游,请设置为false
sourceNpmRegistryIsCNpm: true,

//若安装时模块不存在,是否向源registry进行同步,默认true
syncByInstall: true,

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

// 同步时间间隔,默认10分钟
syncInterval: '10m',

// 是否同步模块中devDependencies,默认false
syncDevDependencies: false,

//用户账号系统接入,可以扩展接入公司的账号系统
//详见https://github.com/cnpm/cnpmjs.org/wiki/Use-Your-Own-User-Authorization
userService: null,
enableAbbreviatedMetadata: true,

安装数据库

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

启动mysql

mysql -uroot -p123456   //mysql  -u 用户名 -p 密码  要跟前面的文件进行数据库配置呀!

创建数据库

create database cnpmjs;

切换到cnpmjs数据库

use cnpmjs;

导入cnpmjs的数据库配置文件 文件是在:/cnpmjs.org/docs/db.sql

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

小小注意:由于cnpmjs.org本身并不支持window环境,所以在window启动需要修改一些东西

直接在当前文件目录下,cmd输入:node dispatch.js

或者修改下package.json ,把"dev": "DEBUG=cnpm* node dispatch.js" 修改为"dev": "set DEBUG=cnpm* node dispatch.js"

https://cdn.nlark.com/yuque/0/2021/png/466273/1609507586762-a16a07bf-c9aa-495e-80db-7a8946e6a3dc.png?x-oss-process=image%2Fresize%2Cw_746

在浏览器地址栏输入:127.0.0.1:7002 回车,打开页面即为成功!

127.0.0.1:7001 也很重要呀,用于发布包和进行权限的作用!

nrm add test http://127.0.0.1:7001
nrm use test
//换成私服状态啦,就可以继续下面的流程啦
//接下来靠自己来一遍啦  ~_~

还有一点需要注意的是包的名称必须含有下图所示的字段,否则一直发布不了,报403错误。npm init 的时候记得取名字的时候带上这个字段。

https://cdn.nlark.com/yuque/0/2021/png/466273/1609507705849-846cdd57-a8fa-4335-8ab0-9aa16b17451e.png

小小扩展 ---私有包存储上云

cnpmjs.org 项目配置项里面有一个 nfs 配置,这里定义了一个 npm 文件系统(NFS)。私有仓库在同步和上传的时候,会交给 NFS 对象相应的函数去处理,NFS 对象返回处理结束之后再返回下载链接,所以通过自定义 NFS 模块可以实现 npm 包的各种定制存储。目前官方默认使用 fs-cnpm,该模块会将上传或者同步的包保存在服务器本地的 /root/.cnpmjs.org/doenloads/ 目录下。这种方式比较传统,一方面随着私有包数量的不断增加,存储资源会是一个瓶颈。另一方面需要定时的备份资源.

这个时候将私有包或者同步的资源放到云上就是一个非常好的方案。cnpmjs.org 官方早就为我们想到了这点,给出了下面几种 NFS 模块:

这些模块已经能够满足我们绝大部分的场景,如果你有特殊的需求,可以参看 nfs模块规范 (https://www.v2ex.com/t/294255) 进行定制化开发。