Build your own npm privatization warehouse with verdaccio

Posted by Kelset on Thu, 16 Dec 2021 12:52:13 +0100

preface

Then the last article What sparks can Gitea+Jenkins collide with? Discussion on front-end automation deployment_ Diehunter 1024 blog - CSDN blog

This article will share with you verdaccio Build a privatized npm warehouse and publish npm packages

preparation

Installing and configuring verdaccio

  1. Use npm install --global verdaccio to install verdaccio globally
  2. Create a new folder in the server to store npm data
  3. Run cmd in the newly created folder, enter verdaccio, and display the following logs
  4. Open in browser http://localhost:4873/ The following page is displayed for the next step
  5. You can know from the log that the yaml file of verdaccio is in C:\Users \ user name \ config\verdaccio\config.yaml, we can customize the file and start it manually. Copy the yaml file to the new folder and modify the file. The following is my configuration file for reference only
    # Data cache directory
    storage: ./storage
    # Plug in directory
    plugins: ./plugins
    
    #Open the web service and access it through the web
    web:
      # Page title name
      #enable: false
      title: NPM-diehunter
    #Verification information
    auth:
      htpasswd:
        #  User information storage directory
        file: ./htpasswd
        # Maximum number of registrants, default infinity
        #max_users: 1000
    
    #Public warehouse configuration
    uplinks:
      npmjs:
        # url: https://registry.npmjs.org/
        # taobao image
        url: https://registry.npmmirror.com/
    
    packages:
      "@*/*":
        # scoped packages
        access: $all
        publish: $authenticated
        #If the agent is not found in the local warehouse, it will find it in npmjs, which is the variable in uplinks
        proxy: npmjs
    
      "**":
        # Authority: owner, anonymous user, authenticated (login) user
        # "$all", "$anonymous", "$authenticated"
    
        #Can I access the required permissions
        access: $all
    
        #Permission to publish package
        publish: $authenticated
    
        # If the package does not exist, a request is made to the upstream service of the agent
        proxy: npmjs
    
    middlewares:
      audit:
        enabled: true
    # Listen to all local ip addresses. After configuration, you can access them through the public network
    listen: 0.0.0.0:10241
    # journal
    logs:
      - { type: stdout, format: pretty, level: http }
      #- {type: file, path: verdaccio.log, level: info}
    
  6. Using the cmd script to start the file, you can write the following command as a bat file and put it in the folder directory
    verdaccio --listen 10241 --config ./config.yaml
  7. Finally, run the command to open the web page
  8. In addition, you can refer to Nginx common instructions, basic configuration, reverse proxy_ Diehunter 1024 blog - CSDN blog , reverse proxy the npm warehouse to the route without occupying the port

Upload code to warehouse

Recommended use nrm Manage the npm warehouse address and switch the warehouse address to http://localhost:10241/

Written before PubSubPattern (publish and subscribe) as an example, create a new package.json file npm init -y in the folder, and configure name, version, etc

{
  "name": "pub_sub_pattern",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Registered user: use npm adduser --registry http://localhost:10241/ Register user, enter user name (in lower case), password and email

Then in index JS write source code

exports.PubSubPattern = class PubSubPattern {
  constructor() {
    this._eventList = {}; //Dispatching center list
  }
  static Instance() {
    //Returns a singleton of an instance of the current class
    !PubSubPattern._instance &&
      Object.defineProperty(PubSubPattern, "_instance", {
        value: new PubSubPattern(),
      });
    return PubSubPattern._instance;
  }
  on(type, handler) {
    if (!checkArgs(type, handler)) {
      return;
    }
    //If the dispatching center does not find the queue of this event, it will create a new event list (multiple callback functions can be registered for a certain type of event)
    !isKeyInObj(this._eventList, type) && (this._eventList[type] = new Array());
    this._eventList[type].push(handler);
  }
  un(type, handler) {
    if (!type) {
      return;
    }
    const fnList = this._eventList[type];
    if (type && (!handler || typeof handler !== "function")) {
      this._eventList[type] = null;
      return;
    }
    for (let i = 0; i < fnList.length; i++) {
      fnList[i] && fnList[i] === handler && (this._eventList[type][i] = null);
    }
  }
  once(type, handler) {
    if (!checkArgs(type, handler)) {
      return;
    }
    const _handler = (args) => {
      this.un(type, _handler);
      handler(args);
    };
    this.on(type, _handler);
  }
  emit(type, module) {
    if (!type) {
      return;
    }
    const fnList = this._eventList[type];
    if (!fnList) {
      return;
    }
    isKeyInObj(this._eventList, type) && fnList.map((_) => _ && _(module));
  }
  clear() {
    this._eventList = {};
  }
}

/**
 * Check whether the object contains this attribute, except for the prototype chain
 * @param obj Checked object
 * @param key Properties of the checked object
 */
function isKeyInObj(obj, key) {
  return Object.hasOwnProperty.call(obj, key);
}
/**
 * Check whether the parameters meet the standards
 * @param type Event name
 * @param handler event hook 
 */
function checkArgs(type, handler) {
  if (!type) {
    return;
  }
  if (!handler || typeof handler !== "function") {
    throw new Error(
      "handler is not defined or not a function at arguements[1]"
    );
  }
  return true;
}

When finished, enter npm publish --registry http://localhost:10241/ Publish code to npm repository

The npm package is released

Installation dependency

Start another test folder and use

npm init -y
npm i pub_sub_pattern

Download dependency

Create a new main in the test folder JS enter the following

const { PubSubPattern } = require("pub_sub_pattern");
console.log(PubSubPattern);
PubSubPattern.Instance().on("event", (data) => {
  console.log(data);
});

setTimeout(() => {
  PubSubPattern.Instance().emit("event", { name: "hunter" });
}, 1000);

And execute node main on the console. The following log indicates success

Write at the end

Finally, we can cooperate with this article What sparks can Gitea+Jenkins collide with? Discussion on front-end automation deployment_ Diehunter 1024 blog - CSDN blog

npm publish --registry http://localhost:10241/ The commands are placed in Jenkins' commands to automatically publish npm, which is the prototype of the micro front end

Thank you for reading here. If this article is helpful to you, please point a praise to support the author! Your support is the driving force of the author's creation~

Topics: Javascript node.js Front-end npm