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.json
and a yarn, they are called yarn.lock
. In npm and yarn, they are placed next to package.json.
package-lock.json
It 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.lock
Different 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:
- The actual installed version of each dependency
- Each dependencies of dependencies
- 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 dependencies
destination 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 twilio
install a named twilio
dependencies. 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.json
file files
configuration and .npmignore
to determine which files should be published files. If you do not .npmignore
file, use .gitignore
the 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, .git
a folder will always be ignored.
After, npm will get a list of files, and use npm pack
to package them into one tarball
. If you want to see which files are packaged, you can run the npm pack --dry-run
command, it will output all files:
Then, this tarball
will be uploaded to npm package repository. When you run this command, you may have noticed, package-lock.json
have not been into the package. This is because package-lock.json
always 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 .gitignore
file:
yarn.lock
package-lock.json
复制代码
yarn official documentation says even if you write a library, it should register a yarn.lock
file. However, if you want to make sure users have the same experience, I would suggest to yarn.lock
add to .gitignore
.
You can turn off package-lock.json
the 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-lockfile
command does not generate a lock file.
However, not to say that because we do not use the package-lock.json
file there is no way to lock dependencies and child dependencies. We can also use another named npm-shrinkwrap.json
file.
It is substantially the package-lock.json
same. A npm shrinkwrap
generation command and the actual npm package and publish it to the warehouse.
Thus, by npm shrinkwrap
even 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 shrinkwrap
file 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-run
does not actually install the dependencies to the project directory, npm publish --dry-run
in 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:
- What is the difference npm ci and npm install is
- What package-lock.json and npm-shrinkwrap.json role?
- List is always packed and always ignored files
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.
Reproduced in: https: //juejin.im/post/5cf61e315188251c06481987