快速摘要
如果你开发像 Web 服务器之类的程序,那么 lock file 是非常有用的。但是如果将库或 CLI 发布到 npm,则永远不要发布 lock file。因为如果你使用它,则意味着你和你的用户可能在使用不同版本的依赖项。
什么是Lock File?
lock file 描述了整个依赖关系树,它在创建时被解析,包括具有特定版本的嵌套依赖关系。在 npm 名为 package-lock.json ,在 yarn 中名为 yarn.lock。在这两个npm和yarn它们被放置旁边你的package.json。
package-lock.json 的内容应该是这样:
yarn.lock 的格式不同,但也包含类似的信息:
两者都包含一些重要的信息:
既然 lock file 中已经列出了所有的依赖项,拿为什么还要将它们写在 package.json 中呢?为什么我们需要两个文件?
package.json vs. Lock File
package.json 中 dependencies 字段显示你的项目应该安装的依赖项,但不显示这些依赖项的依赖项。依赖项可以指定精确版本或 semver 范围。对于 semver 范围,npm 或 yarn 将h会选择最适合的版本。
这意味着,如果在发布新版本时多次运行 npm install ,有可能会得到相同版本的依赖项。例如用 npm install twilio 安装 twilio 这样的依赖项,那么 package.json 中的依赖项可能会存在类似于这样的条目:
如果你查阅 npm 网站上的 semver 文档,就会看到 ^ 意味着任何大于 3.30.3 的版本和小于 4.0.0 都是有效版本。因此,如果在发布新版本时你没有锁定文件,npm install 或 yarn install 会自动安装一个,你的 package.json 将不会被更新。但是 lock file 的内容会有所不同。
如果 npm 或 yarn 找到它们各自的 lock file,将使用它们代替模块安装。这对于持续集成(CI)等情况尤其有用。对于此这种场景,你可以针对相应的包管理器使用特殊命令或标志:
当你在构建 Web 程序或服务器之类的应用时,这非常有用,因为我们希望在 CI 环境中模拟用户的行为。因此,如果在源代码控制(如 git)中跟踪我们的 lock file,就可以确保每个开发人员以及服务器或构建系统还有 CI 系统都能够使用相同版本的依赖项。
那么当我们编写要发布到 npm 的库时,为什么不能做同样的事呢?要回答这个问题,首先要讨论发布的工作原理。
如何发布模块
与某些人想的相反,你发布到 npm 的内容并不总是与 GitHub 上或项目中的内容完全相同。发布模块的方式是 npm 将通过检查 package.json 和 .npmignore 文件中的 files 键或者如果没有``来确定应该发布的文件。 gitignore文件。还有一些文件总是包含在内,有些文件将永远被排除在外。你可以在 [npm page](https://docs.npmjs.com/files/package.json#files) 上找到这些文件的完整列表。例如,.git` 目录始终会被忽略。
之后 npm 将会获取文件列表,并用 npm pack 将它们一起打包成 tarball。如果要查看打包的文件,可以在项目中运行 npm pack --dry-run,能看到包含所有文件的输出:
那个 tarball 将被上传到 npm注册表。运行此命令时你可能会注意到加入你已经有了一个 package-lock.json,它实际上没有被捆绑。这是因为 package-lock.json 将始终被忽略。
这意味着如果另一个开发人员安装了你发布的软件包,他们永远不会下载你的 package-lock.json,因此在安装过程中将会完全忽略它。
这可能会导致“在我的机器上能够工作”的意外,因为你的 CI 和开发环境可能会选择不同的依赖项版本。那么我们可以做些什么呢?
禁用 lock file 并收缩包装
首先,应该停止跟踪我们的 lock file。如果你用的是git,请将以下内容添加到项目中的 .gitignore 文件中:
Yarn 的文档说即使你创建了库,也应该签入 yarn.lock,但是如果你想确保自己能够保证与用户相同的体验,我建议将其添加到 .gitignore。
你可以通过在项目里的 .npmrc 文件中添加以下内容来关闭 package-lock.json 文件的生成:
对于 yarn,你可以通过添加 yarn install --no-lockfile 标志保证不生成 lock file。
摆脱了 package-lock.json 并不意味着无法固定我们所拥有的依赖关系和子依赖关系。我们可以用另一个名为 npm-shrinkwrap.json 的文件。
它与 package-lock.json 基本相同,并由 npm shrinkwrap 生成并实际的打包并发布到 npm 注册表中。
因此,通过将 npm shrinkwrap 添加到 npm 脚本作为 prepack 脚本甚至是 git commit hook,可以确保在你的开发环境中,与你的用户和 CI 中使用相同版本的依赖项。
**一个重要的提示:**通过使用 shrinkwrap 文件,你可以确定精确的版本,但它也会阻止人们获得自动安装的关键补丁程序。 npm 强烈反对库的 shrinkwrap 的用例。
了解更多信息
不幸的是,虽然 npm docs 中有很多相关内容,但有时很难找到你想要的东西。如果你想更好地了解安装或打包的内容,那么你一个常见标志就是 --dry-run。运行该命令而不会影响你的系统。
例如 npm install --dry-run 并不会将依赖项安装到你的文件系统,或者 npm publish --dry-run 实际上也不会发布该包。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VeVb武林网。
新闻热点
疑难解答