Lightweight NPM private repository Verdaccio framework application Guide

This article does not involve the principle analysis of Verdaccio, nor will it copy all the tutorials in the official documents. If readers have corresponding needs, it is recommended to ignore this article and directly go to The Github of Verdaccio to view the source code, or directly go to the official website of Verdaccio document to read first-hand information.

preface

Because the team encountered some problems in the process of using the current NPM private library, so they tried to solve the problem by replacing the original CNPMJS with Verdaccio. However, after my investigation, I found that Verdaccio was not the answer I wanted. I will describe the specific problems later.

This article mainly shares some of my thoughts on trying to deploy Verdaccio locally, and it would be nice if I could help my colleagues who are also confused.

directory

  • Verdaccio profile
  • Verdaccio use
  • Verdaccio advanced
  • gossip
  • The resources
Verdaccio profile
  • What is a Verdaccio

Verdaccio is a lightweight private NPM Proxy Registry created by Node.js.

Set up an internal NPM repository within your local or team network. What the NPM repository can do, the private repository provided by Verdaccio can do.

Verdaccio is actually a fork of sinopia, another NPM proprietary repository framework, which has not been updated for so long that Verdaccio continues as a new open source project. The more active Verdaccio is now recommended.

  • What can Verdaccio do
    • Publish private packages that are not used by people outside the team
    • Use proxy to download packages that do not exist in a private repository
    • Cache packages that are not in the private repository for faster next installation
    • Set access to the private repository
    • Use Docker, AWS and other deployment modes

In fact, for most teams that need to build a private repository, the ability to publish private packages, install private packages, and download private packages is basically enough. Many of the customization requirements that are hard to come up with are rarely available in practical applications. Therefore, there is a greater need to build a private library simply and securely, which is one of the fundamental reasons for Verdaccio’s popularity.

If you have special needs, such as third-party open source packages on the OFFICIAL website of NPM that do not exist in the private library, you can modify the configuration file to set proxy implementation. Verdaccio also provides configuration items for downloading third-party open source packages and caching them in private repositories.

For the permission management of private library, Verdaccio provides the way of configuration file and plug-in access, which is convenient for different users’ foolproof configuration or deep customization.

Verdaccio use

How to use Verdaccio, mainly related to “how to install”, “how to send packages”, “how to download packages” is basically enough.

  • Install Verdaccio
npm install --global verdaccio
Copy the code
  • Start the Verdaccio
    • Ordinary start
    // Enter verdaccio to verdaccioCopy the code
    • Pm2 startup is recommended
    Pm2 NPM install -g pm2 start verdaccio pm2 start VerdaccioCopy the code
    • Visit verdaccio’s Web page
    // The default address is http://localhost:4873/Copy the code
  • Publish locally private packages to private repositories
Json // Run the release command NPM publish --registry http://localhost:4873/ // If login is prompted, run NPM login normallyCopy the code
  • Download a private package from a private repository
// 下载私有仓库的包 your-package
npm install your-package --registry  http://localhost:4873/
Copy the code

At this point, a private repository is basically ready to serve even when deployed. The above commands can be executed directly on a specific private warehouse server within the team.

Verdaccio advanced

The so-called advanced, in fact, is more my personal experience sharing, I hope to give some small ideas to colleagues who want to further study Verdaccio

  • The configuration file

Now if you search Verdaccio in the whole web, in fact, it is basically the above “how to install” + Verdaccio config. Yaml configuration file translation again. How to install I have a simple write, configuration file translation, I will not hard, I directly put the default configuration file posted to you, interested students can read English or use their own software translation, maybe more impressive.

# # This is the default config file. It allows all users to do anything, # so don't use it on production systems. # # Look here for more config file examples: # https://github.com/verdaccio/verdaccio/tree/master/conf # # path to a directory with all packages storage: /Users/allin0943/.local/share/verdaccio/storage # path to a directory with plugins to include plugins: ./plugins web: title: Verdaccio # comment out to disable gravatar support # gravatar: false # by default packages are ordercer ascendant (asc|desc) # sort_packages: asc # convert your UI to the dark side # darkMode: true # translate your registry, api i18n not available yet # 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. # 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 unpublish: $authenticated proxy: npmjs '**': # 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" 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 # You can specify HTTP/1.1 server keep alive timeout in seconds for incoming connections. # 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. # 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. 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 # 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) #i18n: #web: en-USCopy the code
  • The plug-in

As for plugins, I found that most of them are related to auth permissions. If you are interested in playing around with permissions, you can take a look at some plugins provided by the official website documentation. There are only two steps:

* Install auth plugins // select the auth plugins you want, Can refer to https://verdaccio.org/docs/zh-CN/plugin-auth ` ` ` * configuration auth plug-in ` ` ` / / config in the configuration file. The yaml set in the auth:  you_select_auth_plugin ```Copy the code
  • Plug-in development

Verdaccio itself supports the development and use of five plug-ins: verdaccio.org/docs/zh-CN/…

* Authentication Plugin
* Middleware Plugin
* Storage Plugin
* Theme
* Filter plugins
Copy the code
  • customized

Instead of customizing, I wanted to see what we could do as we wanted. Then around the circle, found that based on Verdaccio to guide, can be changed is not much, if you want to change the basic is the need to change the Verdaccio source code, at the same time if you want to change the UI, also need to modify the Verdaccio-UI project, and then package compilation.

One drawback of this is that after deep customization, it is no longer very convenient to enjoy the new functions or optimization after Verdaccio version update. Let me just tell you a little bit about what I found here.

The composition of the entire Verdaccio project:

// The back-end service is developed based on the Express framework // the front-end page is developed based on the React framework. // Data management, no additional database is introduced to manage package files, using the '@verdaccio/local-storage' self-developed database for data management. // Both the front and back end projects are TypeScript implementationsCopy the code

When I wanted to change an element of the home page, I found that I needed to develop and package the Verdaccion-UI library based on React, as well as import and configure Verdaccio’s templatePath.

In the back-end project, the source code for rendering the home page is part of the page (here only to indicate that to change a UI is needed in a special UI project to modify and compile) :

Search.configureStorage(storage); /* eslint new-cap:off */ const router = express.Router(); router.use(auth.webUIJWTmiddleware()); router.use(setSecurityWebHeaders); / / get the front page rendering HTML file const themePath = loadTheme (config) | | the require (' @ verdaccio/UI - the theme ') (); const indexTemplate = path.join(themePath, 'index.html'); const template = fs.readFileSync(indexTemplate).toString(); function renderHTML(req, res) { const protocol = getWebProtocol(req.get(HEADERS.FORWARDED_PROTO), req.protocol); const host = req.get('host'); const { url_prefix } = config; const uri = `${protocol}://${host}`; const base = combineBaseUrl(protocol, host, url_prefix); const language = config? .i18n? .web ?? DEFAULT_LANGUAGE; const darkMode = config? .web? .darkMode ?? false; const primaryColor = validatePrimaryColor(config? .web? .primary_color); const title = _.get(config, 'web.title') ? config.web.title : WEB_TITLE; const scope = _.get(config, 'web.scope') ? config.web.scope : ''; const options = { uri, darkMode, protocol, host, url_prefix, base, primaryColor, title, scope, language }; const webPage = template .replace(/ToReplaceByVerdaccioUI/g, JSON.stringify(options)) .replace(/ToReplaceByVerdaccio/g, base) .replace(/ToReplaceByPrefix/g, url_prefix) .replace(/ToReplaceByVersion/g, pkgJSON.version) .replace(/ToReplaceByTitle/g, title) .replace(/ToReplaceByLogo/g, logoURI) .replace(/ToReplaceByPrimaryColor/g, primaryColor) .replace(/ToReplaceByScope/g, scope); res.setHeader('Content-Type', HEADERS.TEXT_HTML); // We see here, we simply webPage render, and we basically rely on the UI page for more logic, that is to say, we sort of separate the implementation of the rear end of the webPage; }Copy the code

Front-end project routing related part of the source code (here just to explain that we see the jump to http://localhost:4873/ page, in fact, is the implementation of front-end SPA) :

// AppRoute.tsx import { createBrowserHistory } from 'history'; import React, { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { Route as ReactRouterDomRoute, Switch, Router } from 'react-router-dom'; import AppContext from './AppContext'; import loadable from './utils/loadable'; const NotFound = loadable(() => import(/* webpackChunkName: "NotFound" */ 'verdaccio-ui/components/NotFound')); const VersionContextProvider = loadable(() => import(/* webpackChunkName: "Provider" */ '.. /pages/Version/VersionContextProvider') ); const VersionPage = loadable(() => import(/* webpackChunkName: "Version" */ '.. /pages/Version')); const HomePage = loadable(() => import(/* webpackChunkName: "Home" */ '.. /pages/home')); // Routing enumeration, covering all pages supported by Verdaccio, Enum Route {ROOT = '/', SCOPE_PACKAGE = '/-/web/detail/@:scope/:package', SCOPE_PACKAGE_VERSION = '/-/web/detail/@:scope/:package/v/:version', PACKAGE = '/-/web/detail/:package', PACKAGE_VERSION = '/-/web/detail/:package/v/:version', } export const history = createBrowserHistory({ basename: window? .__VERDACCIO_BASENAME_UI_OPTIONS? .url_prefix, }); const AppRoute: React.FC = () => { const appContext = useContext(AppContext); const { t } = useTranslation(); if (! appContext) { throw Error(t('app-context-not-correct-used')); } const { user } = appContext; const isUserLoggedIn = user? .username; return ( <Router history={history}> <Switch> <ReactRouterDomRoute exact={true} path={Route.ROOT}> <HomePage isUserLoggedIn={!! isUserLoggedIn} /> </ReactRouterDomRoute> <ReactRouterDomRoute exact={true} path={Route.PACKAGE}> <VersionContextProvider> <VersionPage /> </VersionContextProvider> </ReactRouterDomRoute> <ReactRouterDomRoute exact={true} path={Route.PACKAGE_VERSION}> <VersionContextProvider> <VersionPage /> </VersionContextProvider> </ReactRouterDomRoute> <ReactRouterDomRoute exact={true} path={Route.SCOPE_PACKAGE_VERSION}> <VersionContextProvider> <VersionPage /> </VersionContextProvider> </ReactRouterDomRoute> <ReactRouterDomRoute exact={true} path={Route.SCOPE_PACKAGE}> <VersionContextProvider> <VersionPage /> </VersionContextProvider> </ReactRouterDomRoute> <ReactRouterDomRoute> <NotFound /> </ReactRouterDomRoute> </Switch> </Router> ); }; export default AppRoute;Copy the code

Then there is the development of plug-ins, not looking at the details, basically Express based middleware development. On the one hand, I haven’t figured out what functions need to be developed for plug-ins, and on the other hand, I haven’t studied the implementation and use of Plugins recommended by Verdaccio’s website, so I won’t repeat them here.

gossip

The team built their own NPM private repository using CNPMJS early on and has been running since then. However, as the project became more and more diverse, some students in the team complained more or less about the existing Npm private warehouse, such as:

  • Now the private warehouse delivery process is more troublesome
  • Installing private packages in a project always fails
  • Private packages are increasingly coupled and difficult to maintain

In the beginning, we are faced with this problem, the thought is the first choice of private warehouse technology scheme has a problem, so in order to solve the team everyone poking fun at the point, I spent some time researching the industry of the technical scheme of the other teams, found that there are a lot of friends recommend try Verdaccio, I also thought that this can solve our problems.

But after a few twists and turns, I reported my conclusion to the team leader and realized we were going the wrong way. Verdaccio itself solves the problem of “helping you and your team build a private NPM repository in an almost zero-configuration way,” and that’s it. When we looked back, we found that the problems our team encountered were more about how to solve the problem of private package release and how to decouple private packages. Of course, this is a later story and we will continue to solve this problem, but it is not the direction of this article.

At this point, after a toss and turn, I have a different understanding of Verdaccio’s feelings, and here is a brief summary, so that if other students need to consider using it, they can have a reference.

  • Verdaccio only solves the problem of how to foolproof deploy a set of NPM private repositories, isn’t it a silver bullet
  • If there is a high need for customization of NPM private warehouse, it is recommended to do secondary development. If there is a need for data statistics, you can consider to access the corresponding database in Express. However, if you are at this stage, why don’t you wonder whether CNPMJS is more suitable for your needs? Of course, I’ll come back to CNPMJS later.
  • Each team has the needs of each team, and each project also has the significance of each project. Do not look at other teams using Verdaccio rashly, so as to cut over the situation without thinking, especially since CNPMJS has been used to build a private library, because there is also a data migration problem, so far, There is no good solution for migrating CNPMJS private packages to Verdaccio (I can think of the following two)
    • Discard the previous version and release it again with the latest version in the new NPM private library
    • Find the corresponding version, manually or by writing a script, and do a batch migration
  • To understand Verdaccio’s “lightweight” positioning, consider its limitations even though it also offers a plug-in approach
  • Through the general depth of the practice, there is an experience is that there is a problem directly masturbate the official document is good, sometimes search too much “tutorial” may not be able to meet your needs, and even by the article time and project version of the impact, resulting in some puzzling problems. There is a lot of articles are simple to the official website, which is why I remind you of the first sentence, directly look at the official website or source code, faster and more accurate.

Finally, recommend a full set of TS tutorials. Recent TS in ascension, collect a set of very good tutorial, free to share with XDM www.yidengxuetang.com/pub-page/in…

The resources

  • Verdaccio documentation: verdaccio.org/docs/zh-CN/…
  • Verdaccio source: github.com/verdaccio/v…
  • Verdaccio UI source: github.com/verdaccio/u…
  • An the Introduction to Verdaccio:jotadeveloper.medium.com/an-introduc…
  • Verdaccio plugin development: verdaccio.org/docs/zh-CN/…

Browse creative Commons license agreements



This work adoptsCreative Commons Attribution – Same way share 4.0 International LicenseGrant permission.