The background,

NPM as a package management tool, whether you are a broad front-end or a large front-end has been inseparable from it 😺

At present, there are many mature open source NPM sources available for use, such as NPM, CNPM, Taobao and so on. However, due to the stability, privacy and security considerations, the company will certainly build its own private warehouse 🧐

The problem is that the private NPM package can only be accessed on the Intranet of the company. When the Intranet cannot be accessed, such as in the delivery scenario, the code needs to be delivered and secondary development needs to be performed on the customer site. The private NPM package cannot be installed 😰

Second, the status quo

Private server installation logic 👇

For example, 🌰 : business engineering Demo NPM packages depend on the following, where the @scope1 scoped packages are private packages, that is, only on the private source, on the non-corporate Intranet, the @scope1 scoped packages cannot be installed 🤯

// package.json
{
  "name": "dmeo"."version": "1.0.0"."scripts": {
    "start": "npm run serve",},"devDependencies": {
    "@commitlint/cli": "11.0.0"."@commitlint/config-conventional": "11.0.0"."@scope1/cli-plugin-babel": "^ 1.0.14"."@scope1/cli-plugin-vue": "^ 1.0.14"."@scope1/cli-service": "^ 1.0.14"."autoprefixer": "10.2.5"."axios": "^ 0.21.1"."babel-eslint": "10.1.0"."babel-plugin-import": "^ 1.13.3"."cross-env": "7.0.3"."cssnano": "4.1.10"."eslint": "7.21.0"."eslint-config-prettier": "8.1.0"."eslint-plugin-prettier": "3.1.4"."eslint-plugin-vue": "7.7.0"."globby": "^ 11.0.3"."husky": "^ 4.3.8"."lib-flexible": "^" 0.3.2."lint-staged": "10.5.4"
  },
  "dependencies": {
    "core-js": "^ 3.8.3"."vue": "The 2.6.12"."vue-router": "3.5.1 track of"."vuex": "3.6.0"."webpack-dev-server": "^ 3.11.2"}}Copy the code

3, requirements,

  • On the non-intranet of company A, the site B has a private server. That is, the public package can be downloaded from the site B private server. The package of company A private server cannot be downloaded and only the private server of company A needs to be processed

    • The @scope1 scoped package (private package) is also installable 👌
    • If the @scope1/package1 dependent subpackage @scope1/ subPackage1 is also a properly installed dependent subpackage @scope1/ SubPackage1… namelySubpackage dependencies @scope1 are installed correctly👌
    • @scope1/package1 depends on subpackages @scope1/[email protected], @scope1/package2 depends on subpackages @scope1/[email protected], @scope1/ subPackage1Version inconsistencyIt can be installed normally 👌
  • On the Intranet of non-company A, the site B selfless service is implemented, that is, all packets need to be processed. In this case, the solution is to set up a private service

4. Common solutions

4.1 Private Server Scenarios

The following solutions usually come to mind at this time: 🤢

  • Publish the NPM private package to an open source NPM source
    • Package stability, privacy, and security problems 🙅♂️
  • Publish the NPM private package to a private NPM source within the customer
    • The source code of the package needs to be delivered to the customer, which causes privacy leakage 🙅♂️
    • The NPM package needs to be released according to the process of releasing the NPM package. The communication and cost are high 😷
  • Take the private packages and put them in a repository that is deployed on the customer system, change the dependency to the repository address, and share the NPM packages with the repository
    • You need to manually copy private packages to git repositories. If there are private packages in the subpackage dependencies of private packages, you need to manually change the private package NPM install address of the subpackage dependencies, recursively. Inefficient and error-prone 🙅♂️
    • The customer needs to deploy another warehouse on site, which follows the customer’s deployment process and costs a lot 😷
  • Set up a temporary private server at the customer site, put the private package on the private server, and rely on the private server installation project
    • Build temporary private service, need to occupy machine resources, consumption of manpower, high cost 😷
    • Private server has stability problems, the machine is affected by the customer’s environment 🙅♂️

4.2 Selfless service scene

Build a private server with Verdaccio

5. Practice plan

NPM install , where the third parameter package is usually the name of the package we want to install. By default, NPM will look up the package address corresponding to the package name from the default Registry source and download the installation

But in the NPM world, a package can be a folder path pointing to a valid package name in addition to simply specifying the package name. The scheme is based on this implementation, as follows: 👇

This tool is designed for the CLI (command line interface)

  • Provide two commands for privatify Package [scope] and Privatify Scope

    . Privatify PACKAGES can be automatically processed as offline packages by executing only one command. In addition, there are also private package scenarios when private buns depend on private packages. The versions of private buns depend on private packages are inconsistent. No other operations are required to process the private server scenarios

  • You can run the Privatify Register Create command to quickly build private services, which can cache NPM packages to private servers in service projects

npm-package-privatify

5.1 introduction

An automated tool that processes private source NPM packages as offline packages

Github address: github.com/zxyue25/npm…

5.2 the use of

The installation

npm install -g npm-package-privatify
Copy the code

The command

1.privatify package <package> [scope]

The declared NPM package package is treated as an offline package, and the offline package package subpackage dependencies are found to contain subpackages under scope. If yes, the package is also treated as an offline package

Scope, support wildcards scope matching rules: www.npmjs.com/package/min…

Parameter : NPM package name

// Process the packageName as a private package
privatify package packageName
Copy the code

After successful execution, there are two changes:

A. This project package.json

/ / modify before."dependencies|| devDependencies": {
    "packageName": "^ 0.3.29",},/ / modified."dependencies|| devDependencies": {
    "packageName": "file:private/packageName-${version}.tar.gz",},Copy the code

B. Add the packageName-${version}.tar.gz file in path private

Parameter [scope] : checks whether the package has dependencies under scope, if it does, it will process subpackage private packages

privatify package @scope1/packageName @scope1
Copy the code

If the subpackage has a private package that depends on scope, there are two more changes:

C, private/@scope1/packageName package.json file

/ / modify before."dependencies|| devDependencies": {
    "@scope1/subPackageName": "^ 0.3.29",},/ / modified."dependencies|| devDependencies": {
    "@scope1/subPackageName": "file:.. /.. /private/@scope1/packageName-${version}.tar.gz",},Copy the code

D. Add subPackageName-${version}.tar.g to the private/@scope1 directory

2,privatify scope <scope>

Provides quick operations to uniformly treat packages under the declared scope as offline packages, find whether packages have dependencies under scope, and process private sub-packages if they do

Scope, support wildcards scope matching rules: www.npmjs.com/package/min…

Parameter 1

: scope to find

// Treat the package under @scope1 as private
privatify scope @scope1
Copy the code
3,privatify create <registry-name>

Create an NPM private server repository

Parameters:

<registry-name> : indicates the name of the private server repository


5.3 Implementation Schematic diagram

NPM package processing as offline package schematic:

Build private server schematic: to be added

Six, summarized

In fact, when a private NPM package needs to be processed as an offline package, this solution expands the scenario based on the service and extracts it into a general solution