preface

A new colleague came, pulled the same project to the local installation dependency after running, but the other three computers are running no problem. The next step is to gradually locate the problem. First, I eliminated the code problem, because the latest code did not work properly on other colleagues’ computers with different systems. After entering Baidu/Google/Github Issue search error, repeatedly pulling the project, restarting the computer, reinstalling the environment and a series of operations, Finally, I located the problem that probably depends on the package version update. There are a total of 90+ dependencies in the project, the main several dependencies are manually locked version, but one package is not locked, and some time ago, it should be released a version update, and there are problems with compatibility with other packages, so the error was reported. Compared to the node_moduels version of a healthy project, the project is running after the change.

Principle of NPM package management

Before thinking about solutions, take a look at NPM package management and dependency versioning. This is done through package.json files. When you install (and save) a package using NPM or update a package, package.json automatically adds a message, including the package name and its version. NPM installs the latest version by default, and then prefixes its version number with a ^ symbol. For example ^1.2.12, it indicates that version 1.2.12 should be used at a minimum. And above that, any version with the same large version number is OK. After all, the smaller and Bugfix versions don’t affect usage at all, so it’s safe to use any more advanced version of the same size.

  • Symbol ^ : indicates that the latest version can be updated if the main version is fixed. For example: vuex: “^3.1.3”, 3.1.3 and above 3.x.x are satisfied.
  • Symbol ~ : Indicates that the latest version can be updated if the previous version is fixed. For example: vuex: “~3.1.3”, 3.1.3 and above 3.1.x are satisfied.
  • Unsigned: Indicates a fixed version number. For example, vuex: “3.1.3”. In this case, version 3.1.3 must be installed.

Why do version dependencies need to be locked

In the absence of version locking, each NPM I execution is preceded by a ^ symbol. If there is a revision or revision update, the corresponding latest version will be automatically installed. In this case, the version of the package installed when you install again may be different from the previous version. Specifically, you can check the actual package version in package-lock.json. For example, A creates A new project and generates the package.json file above, but A installed the dependency earlier. At this time, the latest version of packageA is 2.1.0, which is compatible with the code and has no bugs. Later, B cloned the project of A, and the latest version of packageA was 2.2.0 when the dependency was installed, so the 2.2.0 version would be installed according to semantic NPM, but the API of 2.2.0 version might be changed, resulting in bugs in the code.

This is the problem with package.json. The same package.json can produce different results when installed at different times and in different environments.

In theory this shouldn’t happen because NPM, as part of the open source world, also follows a distribution principle: new releases of the same size should be compatible with older releases. The API should not change when 2.1.0 is upgraded to 2.2.0. However, many open source library developers do not strictly adhere to this distribution principle, leading to the above problem.

In order to generate the same node_modules in different environments, it is necessary to introduce version-dependent locking.

Replace or manage the NPM source

First of all, many students may be used to using CNPM, because the installation speed is much faster than NPM, but in the version dependent locking solution, the most basic rule is: do not use CNPM, because CNPM does not support version dependent locking.

Json, nPM-shrinkwrap. Json, or yarn-lock.json files are all installed from package.json files. So installing dependencies through CNPM does not avoid the above problems. And there are a lot of users feedback CNPM will have a dependency package loss problem.

However, one of the problems with NPM is that the installation speed is too slow. Here, we can use the NPM command and still enjoy the installation speed of CNPM by manually changing the NPM source and NRM.

Manual replacementnpmThe source

NPM config set registry [url]

NPM config get registry

usenrm

Install the NRM

npm i nrm -g

View alternative sources

nrm ls

An error occurs when running a command:

To correct the error, click on C:\Users\ Liang \AppData\Roaming\ NPM \node_modules\ NRM \cli.js:17:20

Modification:

//const NRMRC = path.join(process.env.HOME, '.nrmrc'); (delete)
const NRMRC = path.join(process.env[(process.platform == 'win32')?'USERPROFILE' : 'HOME'].'.nrmrc');
Copy the code

Run NRM ls again, the list is displayed, and an error is reported

In the listed list, the source marked with * is currently in use, and the output above indicates that the current source is the official source.

Switch to a source:nrm use xx

For example, switch to the source: NRM use Taobao

Adding sources (adding private sources within the enterprise or other sources) :

nrm add [registryName] [url]

Delete the source:

nrm del <registryName>

The corresponding time to test a source:

nrm test taobao

Depends on the version locking scheme

There are several possible solutions:

Fixed version in package.json

This is the most straightforward. You can write a fixed version number in package.json, i.e. remove the ~ or ^ from the version number, or install it with –save-exact. But this locks only the outermost layer of dependencies, where other versions of the dependency itself are out of control. So it’s not recommended.

npm + package-lock.json

A package-lock.json file with a fixed version number is generated from the current node_modules directory during the first NPM I session. This file will be automatically updated if new dependencies are installed later. However, if you want to update the version number of a current dependency and lock it into package-lock.josn, you need to manually change the corresponding version in package.json or specify the version number of the dependency to install: NPM I [email protected].

npm + npm-shrinkwrap.json

Manually NPM Shrinkwrap to generate or update a version lock file every time a dependency is added or updated.

yarn+yarn-lock.json

Json is similar to package-lock.josn. Those who are used to using the yarn command can use this mode.

npm ci

NPM CI is similar to NPM install and is commonly used in automated environments such as test platforms, continuous integration, and deployment. The difference is:

  • The project must have a package-lock.json or nPM-shrinkwrap. Json.

  • If the dependencies in package-LOc do not match the package.json dependencies, NPM CI will exit with an error rather than update package-lock.

  • NPM CI can only install the entire project at once: you cannot add a single dependency using this command.

  • If node_modules already exists, it will be removed automatically before the INSTALLATION of NPM CI begins.

  • It never writes package.json or any lock: the installation is basically frozen.

NPM CI must have package-lock.json and dependencies that match package.json to install dependencies, otherwise an error is reported, forcing developers to resolve dependencies locally before continuous integration.

yarn –frozen-lockfile

Yarn –frozen lockfile Similar to NPM CI, yarn-lock.json file is required