What we should not use the lock file

One of the most common scenarios encountered when debugging a program might be "on my computer obviously good." This is usually due to the bug and its own program with the underlying system depends different results. Therefore, yarn and npm in the introduction of the "lock files", can track the exact version dependencies. However, when you develop will be released to npm package, should avoid the use of such lock files. In this post, we will discuss why it is.

Quick summary

If you build an application similar to the web server, then the lock files are useful. However, if you publish to the library or CLI npm, then never release the lock file. If you use the lock file, it means that you and your users may use different versions of dependencies.

What is a lock file?

A lock file describes the entire dependency tree, because it is resolved when creating, including dependencies on specific versions of nesting. In npm, these are referred to package-lock.jsonand a yarn, they are called yarn.lock. In npm and yarn, they are placed next to package.json.

package-lock.jsonIt looks like this:

{
 "name": "lockfile-demo",
 "version": "1.0.0",
 "lockfileVersion": 1,
 "requires": true,
 "dependencies": {
   "ansi-styles": {
     "version": "3.2.1",
     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
     "requires": {
       "color-convert": "^1.9.0"
     }
   },
   "chalk": {
     "version": "2.4.2",
     "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
     "requires": {
       "ansi-styles": "^3.2.1",
       "escape-string-regexp": "^1.0.5",
       "supports-color": "^5.3.0"
     }
   }
 }
}
复制代码

yarn.lockDifferent file formats, but it contains similar information:

# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


ansi-styles@^3.2.1:
  version "3.2.1"
  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
  integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
  dependencies:
        color-convert "^1.9.0"

chalk@^2.4.2:
  version "2.4.2"
  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
  integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
  dependencies:
        ansi-styles "^3.2.1"
        escape-string-regexp "^1.0.5"
        supports-color "^5.3.0"
复制代码

Both documents are recorded some important information:

  1. The actual installed version of each dependency
  2. Each dependencies of dependencies
  3. Parsed packet including a checksum, used to validate the integrity of the package

So, if all dependencies are listed in the lock file, why they are listed in package.json in it? Why do we need two documents?

package.json vs. Lock File

Project "package.json" file in the dependenciesdestination field is to show dependencies should be installed instead of these dependencies dependencies. Dependency can specify the exact version or the version number in the range Semver. For semver version number of the rule, npm or yarn will select the most appropriate installed version.

This means that if run twice during a new version is released npm install, you may actually get a different version dependencies. For example, if you npm install twilioinstall a named twiliodependencies. json might have a similar entry:

{
  "dependencies": {
     "twilio": "^3.30.3"
  }
}
复制代码

If you look on page npm semver document , you will find that ^actually means less than any version greater than 3.30.3 and 4.0.0 are valid. Therefore, if any new version is released, and you do not have a lock file exists, npm or yarn will install the new version will not be automatically updated package.json. However, if the lock file does not exist like this.

If npm yarn or find their own lock file, they will use these files to install the module. This situation is particularly useful for like the need to ensure continuous integration (CI) platform test run in a predictable environment. For this use case, you can use special commands or flags with the appropriate package manager:

npm ci # 将确切地安装package-lock.json中的内容
yarn install --frozen-lock-file # 将准确地安装yarn.lock中的内容。不更新锁定
复制代码

This is useful when building a web application or an application server such as in a CI environment, we want to simulate user behavior. So, if we start tracking lock file (such as git) in source control, we can ensure that every developer, server, build dependency system and CI system use the same version.

So, when we write library or other plans to publish something npm warehouse, why do not want to do the same thing? To answer this question, we must first talk about how bidding works.

How to publish module

Some people with general cognitive different, npm publish the content is not always the same as the content on GitHub, it is not always the same as the overall content of the project. Module released way, npm by examining the package.jsonfile filesconfiguration and .npmignoreto determine which files should be published files. If you do not .npmignorefile, use .gitignorethe file. Some files are always included, while other documents are always excluded. You can find these files on the page npm complete list . For example, .gita folder will always be ignored.

After, npm will get a list of files, and use npm packto package them into one tarball. If you want to see which files are packaged, you can run the npm pack --dry-runcommand, it will output all files:

Then, this tarballwill be uploaded to npm package repository. When you run this command, you may have noticed, package-lock.jsonhave not been into the package. This is because package-lock.jsonalways will be ignored, as npm document list as specified.

This means that if you publish a package to install other developers, they will never download you package-lock.json. Therefore, completely unaffected by lock file during installation.

This may unexpectedly cause "in my machine is obviously good" effect because your CI environment and developers can get different versions of dependencies. So what should we do about it?

Disabling file locking and file Shrinkwrapping

First of all, we should make sure to stop tracking lock file. If you are using git, add the following to the project .gitignorefile:

yarn.lock
package-lock.json
复制代码

yarn official documentation says even if you write a library, it should register a yarn.lockfile. However, if you want to make sure users have the same experience, I would suggest to yarn.lockadd to .gitignore.

You can turn off package-lock.jsonthe generated files. By creating or adding the following to the file in the project .npmrc

package-lock = false
复制代码

For yarn, you can use the yarn install --no-lockfilecommand does not generate a lock file.

However, not to say that because we do not use the package-lock.jsonfile there is no way to lock dependencies and child dependencies. We can also use another named npm-shrinkwrap.jsonfile.

It is substantially the package-lock.jsonsame. A npm shrinkwrapgeneration command and the actual npm package and publish it to the warehouse.

Thus, by npm shrinkwrapeven git commit hook Add to npm script as a pre-packaged script, you can be sure to use the same version dependencies in the development environment, users and the CI.

It is important , we must be careful to use. By using shrinkwrapfile dependencies installed, you can lock the exact version, which may be great, but it can also block people's access to critical patches. npm strongly opposed to the use of the library shrinkwrap, and suggested that only in CLIs or similar scene shrinkwrap.

How can I get more information

Although there are a lot of information in this regard in npm document, but sometimes hard to find. If you want to better understand what you want to install or packaged, it is a common command --dry-run. Run this command does not affect the application. For example, npm install --dry-rundoes not actually install the dependencies to the project directory, npm publish --dry-runin fact, will not release package.

Here are some commands you might want to view:

npm ci --dry-run # 基于package-lock.json 或者 npm-shrinkwrap.json文件模拟安装
npm pack --dry-run # 列出了所有要打包的文件以及元信息
npm install <dep> --verbose --dry-run # 将以verbose模式运行包的安装,而无需实际将其安装到文件系统
复制代码

Some useful documentation links on the subject as follows:

Much depends on how to deal with npm package, distribute and install dependencies, and with the changing environment, which may change at some point. I hope this article allows you to have more understanding of this complex topic.

原文:When Not to Use Lock Files with Node.js

Reproduced in: https: //juejin.im/post/5cf61e315188251c06481987

Guess you like

Origin blog.csdn.net/weixin_34174105/article/details/91443977