草庐IT

docker搭建私有npm仓库

volodyan 2023-12-21 原文

一、dockerhub搜索verdaccio/verdaccio镜像

  

 二、docker拉取镜像

docker pull verdaccio/verdaccio:latest

 三、查看镜像

docker image ls

 

四、运行容器 


docker run -it -d --name verdaccio -p 4873:4873 verdaccio/verdaccio

 或者

docker run -it -d --name verdaccio -p 4873:4873 -v /home/verdaccio/storage:/verdaccio/storage -v /home/verdaccio/conf:/verdaccio/conf -v /home/verdaccio/plugins:/verdaccio/plugins verdaccio/verdaccio
  1.  运行mkdir /home/verdaccio,创建 /home/verdaccio 目录
  2. cd /home/verdaccio,进入/home/verdaccio 目录
  3. mkdir storage,创建storage目录
  4. mkdir conf,创建conf目录
  5. mkdir plugins,创建plugins目录
  6. -v 宿主机:容器,容器目录映射到宿主机目录

   注意: 宿主机目录 /home/verdaccio/storage 需要设置权限,不然会因为权限问题而导致操作失败。

verdaccio 容器中创建的用户是verdaccio,无法写入主机 root 用户的文件,容器内 verdaccio 使用的 uid 为 10001,gid 为 65533,可以在主机修改权限

chown -R 10001:65533 /home/verdaccio/storage
chown 10001:65533 /home/verdaccio/conf

   宿主机目录映射成功后,会简化很多操作,比如:  
  在 /home/verdaccio 目录下会创建 storage 目录,如果发布了包,则在此目录下的 data 中能找到对应的包文件夹,可以查看所有上传的npm包,此处也可以直接删除该包;  在 /home/verdaccio 目录下会创建conf 目录,配置文件会映射到此目录下,方便我们需要时修改配置信息。

拷贝 verdaccio 配置文件

 如果不想做本地目录映射,也可以使用如下命令,拷贝出 verdaccio 镜像的配置文件。  
  docker cp:在容器和本地文件系统之间,拷贝文件或文件夹。

docker cp verdaccio:/verdaccio/conf/config.yaml /home

 五、私有库部署成功,查看容器

docker ps -a

 六、浏览器访问私有库

 浏览器访问http://ip:4873

七、安装nrm 

nrm是npm的一个镜像源管理工具,可帮助快速切换镜像源,方便管理。在终端(Mac)或者cmd命令窗口(windows)输入命令,全局安装 

npm install nrm -g

 查看版本

nrm -V

 八、nrm使用

查看可供选择的源 

nrm ls

  • 查看当前源:nrm current
  • 切换源:nrm use <registry>
  • 添加源:nrm add <registry> <url> 例如: nrm add aaaaa https://aaaaa.com
  • 删除源:nrm del <registry>
  • 测试源的响应时间:nrm test <registry>

 添加源私有npm源

nrm add myregistry http://133.269.67.168:8773/

九、发布一个包

有了私有库以后,就可以在其上发布 npm 包。但初始化时需要先添加用户,设置用户名和密码等,然后就可以直接发包了。

  • 添加用户

    npm adduser --registry http://0.0.0.0:4873/
    

    输入用户名、密码和邮箱。

  •  

  • publish

    当需要把某个项目发布到私有库时,直接 publish

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

    发布成功后,刷新页面,就能看到最新发布的包。

  • install

       在项目目录下增加 .npmrc 文件,指定仓库地址。

registry=http://0.0.0.0:4873/

        使用 npm install 包名,即可安装私有包了。

十、vue发布组件库

 1、添加上面刚部署好的私有npm镜像仓库

nrm add myregistry http://133.269.67.128:4873/

 2.查看刚添加的私有npm镜像仓库

nrm ls

3.使用刚添加的私有npm镜像仓库

nrm use myregistry

 4.创建一个vue项目开发组件库

vue create volodyaui

 5.开发组件

在src目录下新建package文件夹,在src/package目录下新建index.js文件,在src/package目录下新建my-button文件夹和my-clock文件夹,在src/package/my-button目录和src/package/my-clock目录下分别新建index.vue

 src/package/index.js

出口文件:引入封装好的组件进行批量注册,然后导出。

// 引入封装好的组件
import MyButton from "../package/my-button/index.vue";
import MyClock from "../package/my-clock/index.vue";
import MyCustomchart from "../package/my-customchart/index.vue";

// 将来如果有其它组件,都可以写到这个数组里
const coms = [MyButton, MyClock, MyCustomchart];

// 批量组件注册
const install = function (Vue) {
    coms.forEach((com) => {
        Vue.component(com.name, com);
    });
};


// 注意这里的判断,很重要
if(typeof windwo !== 'undefined' && window.Vue) {
    window.Vue.use(comment)
  }
  
export default install; // 这个方法以后再使用的时候可以被use调用

为什么导出为install?
安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为install 方法。install 方法调用时,会将 Vue 作为参数传入。 

 src/package/my-button/index.vue

<template>
    <button @click="handleClick" :disabled='disabled'>
        <slot></slot>
    </button>
</template>
<script>
export default {
    name: "MyButton",
    props: {
        disabled: Boolean
    },
    methods: {
        handleClick(evt) {
            this.$emit('click', evt);
        }
    }
};
</script>

 src/package/my-clock/index.vue

<template>
  <div id="clock">
    <div class="box" :style="{ color: textColor }">
      <span class="date">{{ date }}</span>
      <span class="time">{{ time }}</span>
    </div>
  </div>
</template>
<script>
export default {
  name: "MyClock",
  props: {
    textColor: {
      type: String,
      default: "#2cf3fb",
    },
  },
  data() {
    return {
      timer: null,
      date: "",
      time: "",
    };
  },
  created() {
    this.updateTime();
  },
  mounted() {
    this.timer = setInterval(() => {
      this.updateTime();
    }, 1000);
  },
  methods: {
    updateTime() {
      let date = new Date();
      let sDate = "-";
      let sTime = ":";

      let YYYY = formatHandle(date.getFullYear());
      let MM = formatHandle(date.getMonth() + 1);
      let DD = formatHandle(date.getDate());

      let hh = formatHandle(date.getHours());
      let mm = formatHandle(date.getMinutes());
      let ss = formatHandle(date.getSeconds());

      let w = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
      let week = w[date.getDay()];

      this.date = YYYY + sDate + MM + sDate + DD + ` ${week}`;
      this.time = hh + sTime + mm + sTime + ss;

      function formatHandle(value) {
        if (value >= 0 && value < 10) return "0" + value;
        else return value;
      }
    },
  },
  beforeDestroy() {
    clearInterval(this.timer);
  },
};
</script>
<style lang="scss" scoped>
#clock {
  font-family: "Share Tech Mono", monospace;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  .box {
    text-align: center;
    .date {
      font-size: 28px;
      letter-spacing: 2px;
      display: inline-block;
      padding-bottom: 10px;
    }
    .time {
      letter-spacing: 6px;
      font-size: 80px;
    }
  }
}
</style>

6.修改项目的package.json文件

  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --target lib ./src/package/index.js --name volodyaui --dest volodyaui"
  },

 package.json文件

{
  "name": "volodyaui",
  "version": "0.1.0",
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --target lib ./src/package/index.js --name volodyaui --dest volodyaui"
  },
  "dependencies": {
    "core-js": "^3.8.3",
    "vue": "^2.6.14"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "sass": "^1.32.7",
    "sass-loader": "^12.0.0",
    "vue-template-compiler": "^2.6.14"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

利用了vue-cli的构建方法,构建单独的入口
-- target lib 关键字 指定打包的目录 后面可以接上entry打包入口

-- name 打包后的文件名字
-- dest 打包后的文件夹的名称

7.打包开发好的组件库 

npm run build

 打包成功后会在项目根目录下生成volodyaui文件夹

 8.上传打包好的组件库代码

 终端进入刚打包成功生成的volodyaui文件夹目录下

 在该目录下,初始化package.json文件目录

作为一个组件库,我们必须按照npm的发包规则来编写我们的package.json, 我们先来解决组件库打包的问题,首先我们需要让脚手架编译我们的组件代码,并输出到指定目录下,我们按照发包规范一般会输出到lib目录下,代码如下:

组件库上传npm需要按照npm规则来编写package.json。

npm init -y

 修改刚生成的package.json文件

  "keywords": [
    "MyButton",
    "MyCloc",
    "MyCustomchart"
  ],
  "author": "",
  "license": "MIT",
  "private": false,
  "homepage": "https://github.com/1t1824d/volodyaui", 
  "bugs": {
    "url": "https://github.com/1t1824d/volodyaui"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/1t1824d/volodyaui"
  },
{
  "name": "volodyaui",
  "version": "1.0.0",
  "description": "",
  "main": "volodyaui.common.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "MyButton",
    "MyCloc",
    "MyCustomchart"
  ],
  "author": "",
  "license": "MIT",
  "private": false,
  "homepage": "https://github.com/1t1824d/volodyaui", 
  "bugs": {
    "url": "https://github.com/1t1824d/volodyaui"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/1t1824d/volodyaui"
  },

  "dependencies": {
    "core-js": "^3.8.3",
    "echarts": "^5.3.1",
    "vue": "^2.6.14"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "sass": "^1.32.7",
    "sass-loader": "^12.0.0",
    "vue-template-compiler": "^2.6.14"
  }
}

 

npm login(登录)

npm login

注意:

  1. 输入密码时,默认是不显示的,正常输入就行
  2. npm whoami 可以测试当前是否是登录

测试当前是否是登录 

npm whoam

 npm publish (发布)

npm publish

 注意:
1.私有包@开头的,发布时需要添加 --access public

npm publish --access public

 【特别提醒】:确保本地源服务是 registry.npmjs.org,国内大家都喜欢使用taobao镜像源,但是发布不能发到该服务器上。本人使用 nrm 工具进行镜像源的管理和切换。即需要把组件库发布到哪个npm镜像仓库,就需要把当前使用的源切换到哪个npm源。

9.查看刚发布到私有仓库的组件库

10.安装刚发布成功的UI组件库 

 安装

npm install volodyaui

 引入

import volodyaui from "volodyaui"
import "volodyaui/volodyaui.css";
Vue.use(volodyaui)

使用

  <my-button disabled>222</my-button>
  <my-button>333</my-button>
  <my-clock textColor="red"></my-clock>

浏览器查看

volodyaui:GitHub - 1t1824d/volodyaui

有关docker搭建私有npm仓库的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  4. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  5. ruby - 从另一个私有(private)方法中使用 self.xxx() 调用私有(private)方法 xxx,导致错误 "private method ` xxx' called” - 2

    我正在尝试获得良好的Ruby编码风格。为防止意外调用具有相同名称的局部变量,我总是在适当的地方使用self.。但是现在我偶然发现了这个:classMyClass上面的代码导致错误privatemethodsanitize_namecalled但是当删除self.并仅使用sanitize_name时,它会起作用。这是为什么? 最佳答案 发生这种情况是因为无法使用显式接收器调用私有(private)方法,并且说self.sanitize_name是显式指定应该接收sanitize_name的对象(self),而不是依赖于隐式接收器(也是

  6. ruby - 如何在 Ruby 中实现私有(private)内部类 - 2

    来自Java,我正在尝试在Ruby中实现LinkedList。我在Java中实现它的通常方法是有一个名为LinkedList的类和一个名为Node的私有(private)内部类,其中LinkedList的每个对象都作为Node对象。classLinkedListprivateclassNodeattr_accessor:val,:nextendend我不想将Node类暴露给外部世界。然而,通过Ruby中的这个设置,我可以使用这个访问LinkedList类之外的私有(private)Node类对象-node=LinkedList::Node.new我知道,在Ruby1.9中,我们可以使用

  7. ruby 私有(private)类方法助手 - 2

    您好,我正在尝试创建一个帮助程序,用于将ruby​​方法大量定义为私有(private)类方法。通常,可以通过使用private_class_method键工作将方法定义为私有(private)类方法。但我想创建一个以下样式的助手:classPersondefine_private_class_methodsdodefmethod_oneenddefmethod_twoendendend我计划通过以下方式动态定义它,但根本不起作用:classObjectdefself.define_private_class_methods&blockinstance_evaldoprivate&bl

  8. ruby - 使实例方法在运行时私有(private) - 2

    在另一个对象中注册该对象后,我需要将一些实例方法设为私有(private)。我不想卡住对象,因为它必须保持可编辑状态,只是功能较少。而且我不想取消定义这些方法,因为它们是在内部使用的。我需要的是这样的:classMyClassdefmy_methodputs"Hello"endenda=MyClass.newb=MyClass.newa.my_method#=>"Hello"a.private_instance_method(:my_method)a.my_method#=>NoMethodErrorb.my_method#=>"Hello"有什么想法吗?

  9. ruby - Ruby 导入的方法总是私有(private)的吗? - 2

    最好用一个例子来解释:文件1.rb:deffooputs123end文件2.rb:classArequire'file1'endA.new.foo将给出错误“':调用了私有(private)方法'foo'”。我可以通过执行A.new.send("foo")来解决这个问题,但是有没有办法公开导入的方法?编辑:澄清一下,我没有混淆include和require。另外,我不能使用正常包含的原因(正如许多人正确指出的那样)是因为这是元编程设置的一部分。我需要允许用户在运行时添加功能;例如,他可以说“run-this-app--includefile1.rb”,应用程序的行为将根据他在file1

  10. ruby - Ruby gems 的问题(损坏?)试图让指南针在 npm 中工作 - 2

    我不是Ruby专家,但想弄清楚发生了什么,因为我试图让指南针在节点应用程序中工作,但我的Ruby似乎坏了。打字:ruby--version让我:ruby2.1.1p76(2014-02-24revision45161)[x86_64-darwin13.0]我安装了Homebrew,之前遇到过Ruby版本的问题,但它似乎已安装并且可以正常工作。但是,当我使用gem输入请求时,出现此错误:$gem-hErrorloadingRubyGemsplugin"/Users/user_dir/.rvm/gems/ruby-2.1.1@global/gems/executable-hooks-1.3

随机推荐