当前位置: 首页 > 后端技术 > Node.js

LockFiles

时间:2023-04-03 12:20:08 Node.js

不能用在Node.js中的时候就可以了!”这种场景大概是调试bug时最常见的问题了,这通常是系统对故障机器和你自己的底层依赖不同导致的结果机器。所以yarn和npm引入了所谓的“锁定文件”来跟踪依赖项的确切版本。但是在开发要发布到npm的包时应该避免使用这种锁定文件。在这篇文章中,我们讨论了为什么会这样。快速总结(tl;dr)如果你开发像web服务器这样的程序,锁定文件非常有用。但是如果将库或CLI发布到npm,永远不要发布锁定文件。因为如果你使用它,这意味着你和你的用户可能正在使用不同版本的依赖项。什么是锁文件?锁文件描述了整个依赖树,在创建时解析,包括具有特定版本的嵌套依赖项。命名为package-lock。npm中的json和yarn中的yarn.lock。在npm和yarn中,它们都放在你的package.json旁边。package-lock.json的内容应该是这样的:{"name":"lockfile-demo","version":"1.0.0","lockfileVersion":1,"requires":true,"dependencies":{“ansi-styles”:{“版本”:“3.2.1”,“已解决”:“https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz”,“完整性”:“sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==”,“需要”:{“颜色转换”:“^1.9.0”}},“versionchalk”:{2","已解决":"https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz","完整性":"sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQ==U4peSu","requires":{"ansi-styles":"^3.2.1","escape-string-regexp":"^1.0.5","supports-color":"^5.3.0"}}}}yarn.lock具有不同的格式,但也包含类似的信息:#THISISANAUTOGENERATEDFILE。不要直接编辑此文件。#yarnlockfilev1ansi-styles@^3.2.1:version"3.2.1"resolved"https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"integritysha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==dependencies:color-convert"^1.9.0"chalk@^2.4.2:版本"2.4.2"解决了"https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"完整性sha512-Mti+f9lpJNcwF4tWV8/OrTTtWFcF2g+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==dependencies:ansi-styles"^3.2.1"escape-string-regexp"^1.0.5"supports-color"^5.3.0"两者都包含一些重要信息:依赖项的实际版本。每个依赖的依赖都解析了,包的完整性用checksum来校验,既然所有的依赖都在lock文件里列出来了,那为什么还要写在package.json里呢?为什么还要两个文件package.jsonvs.LockFilepackage.json中的dependencies字段显示你的项目应该安装的依赖项,但不是那些依赖项的依赖项依赖项可以指定确切的版本或semver范围。对于semver范围,npm或yarn将选择最合适的版本。这意味着如果您在发布新版本时多次运行npminstall,则有可能获得相同版本的依赖项。例如,如果您使用npminstalltwilio安装twilio等依赖项,那么package.json中的依赖项可能具有类似这样的条目:{"dependencies":{"twilio":"^3.30.3"}}如果您检查如果您查看npm站点上的semver文档,您会看到^表示任何大于3.30.3且小于4.0.0的版本都是有效版本。因此,如果您在发布新版本时不锁定该文件,npminstall或yarninstall将自动安装一个并且您的package.json将不会更新。但是锁文件的内容会有所不同。如果npm或yarn找到它们各自的锁定文件,它们将被使用而不是模块安装。这对于持续集成(CI)之类的事情特别有用。对于这种情况,您可以为相应的包管理器使用特殊命令或标志:npmci#将准确安装package-lock.jsonyarninstall--frozen-lock-file#将准确安装yarn中的内容。lockwithoutupdatingit这在构建web程序或服务器等应用程序时非常有用,因为我们要在CI环境中模拟用户行为。因此,如果我们像git一样在源代码控制中跟踪我们的锁定文件,我们可以确保每个开发人员以及服务器或构建系统以及CI系统都能够使用相同版本的依赖项。那么为什么我们在编写库发布到npm时不能做同样的事情呢?要回答这个问题,让我们首先讨论发布的工作原理。如何发布模块与某些人的想法相反,您发布到npm的内容并不总是与GitHub上或您项目中的内容完全相同。模块发布的方式是npm将通过检查package.json和.npmignore文件中的文件键或者如果没有`..gitignore文件。还有一些文件始终包含在内,而一些文件始终排除在外。您可以在npm页面上找到这些文件的完整列表。例如,.git目录总是被忽略。然后npm将获取文件列表并使用npmpack将它们打包到一个tarball中。如果你想看到打包后的文件,你可以在项目中运行npmpack--dry-run,你可以看到包含所有文件的输出:tarball将被上传到npm注册表。运行此命令时,您可能会注意到添加了您已经拥有的package-lock.json,但它实际上并未捆绑。这是因为package-lock.json将始终被忽略。这意味着如果其他开发人员安装了您发布的包,他们将永远不会下载您的package-lock.json,因此在安装过程中它会被完全忽略。这可能会导致“在我的机器上工作”的意外,因为您的CI和开发环境可能会选择不同版本的依赖项。所以,我们能做些什么?禁用锁文件和收缩包装首先,应该停止对锁文件的跟踪。如果您使用的是git,请将以下内容添加到您项目中的.gitignore文件中:sure为了能够保证和用户自己一样的体验,我建议将这个添加到.gitignore。您可以通过在项目中的.npmrc文件中添加以下内容来关闭package-lock.json文件的生成:package-lock=false对于yarn,您可以通过添加yarninstall-来确保不会生成锁定文件--无锁文件标志。摆脱package-lock.json并不意味着我们拥有的依赖项和子依赖项无法固定。我们可以使用另一个名为npm-shrinkwrap.json的文件。它与package-lock.json基本相同,由npmshrinkwrap生成,用于实际打包并发布到npm注册表。因此,通过将npmshrinkwrap作为预打包脚本或什至作为git提交挂钩添加到npm脚本中,您可以确保在开发环境中使用与用户和CI相同版本的依赖项。重要说明:通过使用shrinkwrap文件,您可以确定确切的版本,但它也会阻止人们自动安装关键补丁。npm强烈反对对库使用shrinkwrap的用例。了解更多不幸的是,虽然npm文档中有很多相关内容,但有时很难找到您要查找的内容。如果您想更好地了解正在安装或打包的内容,一个常见的标志是--dry-run。在不影响您的系统的情况下运行此命令。例如npminstall--dry-run不会将依赖项安装到您的文件系统,或者npmpublish--dry-run实际上不会发布包。以下是您可能想要检查的一些命令:npmci--dry-run#基于package-lock.json或npm-shrinkwrap.json的模拟安装npmpack--dry-run#列出所有将被打包的文件up以及metainfonpminstall--verbose--dry-run#将以详细模式运行包的安装,而不实际将其安装到您的文件系统一些有用的链接:What'sthedifferencebetweennpmciandnpminstallWhat's在一个package-lock.json或npm-shrinkwrap.json文件列表中总是被打包并且总是被忽略