从命令行更新具有固定依赖项的 npm 包 [英] Update npm package with fixed dependency from command line

查看:66
本文介绍了从命令行更新具有固定依赖项的 npm 包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 npm 包,其中有一个有更新的固定版本.
示例 package.json 提取:

devDependencies: {"someFixedVersionPackage": "1.0.0",//1.1.0是最新的"anotherFixedVersionPackage": "2.3.2",//2.3.4是最新的}

是否存在安装该软件包的最新版本并更新 package.json 的 npm 命令,最好一次更新所有软件包?

明确地说,除了包本身被更新之外,我还希望将上面的 package.json 片段更新为此:

devDependencies: {"someFixedVersionPackage": "1.1.0",//最新"anotherFixedVersionPackage": "2.3.4",//最新}

谢谢.

解决方案

为什么 npm update 在这里不起作用?

根据 npm update 上的文档:

<块引用>

此命令会将列出的所有软件包更新为最新版本(由标签配置指定),尊重 semver.

它还会安装缺少的包.与所有安装包的命令一样,--dev 标志也会导致 devDependencies 被处理.

由于您的软件包是使用固定版本定义的,因此 update 子命令不会更新这些软件包以遵守语义版本控制.因此,如果您为每个包指定更大的版本范围,它只会自动更新您的包.请注意,在 npm 项目中实际上通常指定一个宽松的版本;一种旨在避免破坏性更改但仍留有改进和修复空间的方法.

不过,为什么我不应该在 package.json 中修复依赖版本?

<块引用>

但它们是固定的,因为我想要它们.测试新版本后,我想通过命令行更新它们.

具有固定版本的依赖项列表并不意味着安装的依赖项将始终相同,因为依赖项的依赖项很可能也定义了版本范围.为了跟踪经过测试的版本标记依赖项列表,npm 提供了另一种机制:包裹锁.

在 npm 5 版本之前,您可以使用 shr​​inkwrap 命令创建npm-shrinkwrap.json"文件:

<块引用>

npm 收缩包装

此命令会锁定软件包依赖项的版本,以便您可以在安装软件包时准确控制将使用每个依赖项的哪个版本.

从 npm 5 开始,当 npm 操作修改node_modules"树或package.json"时,会自动生成package-lock.json".

这些包锁中的任何一个都不会修改 package.json,而是会覆盖 npm install 的默认行为,在创建或手动更新时使用锁指定的版本安装依赖项.这样一来,您现在可以扩展您的依赖项,而不必担心依赖项安装未经测试的软件包版本.

Shrinkwraps 用于发布包.要收缩包装包裹:

  1. 在包根目录中运行 npm install 以安装所有依赖项的当前版本.
  2. 验证软件包在这些版本中是否按预期工作.
  3. 运行 npm shrinkwrap,将 npm-shrinkwrap.json 添加到 git,然后发布你的包.

此时,可以在 package.json 中放宽依赖版本(希望每次主要依赖更新都只执行一次),以便以后可以使用 npm update:

"devDependencies": {"someFixedVersionPackage": "^1.0.0","anotherFixedVersionPackage": "^2.3.2",}

package-lock.json 文件可以代替shrinkwrap,更适合复现开发环境.它也应该提交到存储库.

那么如何更新我的依赖项?

调用 npm update 将执行上面提到的操作:在尊重语义版本控制的同时更新依赖项.在包中添加或升级依赖项:

  1. 在包根目录中运行 npm install 以安装所有依赖项的当前版本.
  2. 添加或更新依赖项.npm install --save 单独更新每个新的或更新的包以更新 package.json 以及现有的包锁(package-lock.json"和npm-shrinkwrap.json").请注意,它们必须明确命名才能安装:不带参数运行 npm install 只会重现锁定的依赖项.
  3. 验证该包是否按预期与新依赖项配合使用.
  4. 提交新的包锁.

此外,这里有一些从具有固定依赖项的项目平稳过渡的技巧:

  • 如果您还没有这样做,请通过添加波浪号来扩展版本范围 (~) 在版本说明符之前,或插入符号 (^).npm update 然后将尝试分别安装所有补丁修订和次要修订(主要版本 0 是一个极端情况,请参阅文档).例如,^1.0.0"现在可以更新为^1.1.0",~2.3.2"可以更新为~2.3.4".添加 --save--save-dev 标志也会使用已安​​装的版本更新package.json"(同时保留之前的范围说明符).

  • 运行 npm outdated 以检查哪些软件包已过时.红色条目将使用 npm update 自动更新.其他条目需要人工干预.

  • 对于具有主要版本颠簸的软件包,请安装具有版本规范的软件包(例如 npm install browserify@11.2.0 --save-dev).更新可能出现的其他问题必须手动处理.阅读该软件包的新闻提要或发布历史通常有助于进一步了解与以前版本相比发生了什么变化.

这还不够简单,还有其他方法吗?

在继续之前,始终值得一提的是,出于某种原因,软件包具有符合 SemVer 的版本定义.应该避免盲目安装每个软件包的最新版本.虽然这样一个完整的更新可以完成,并且有可用的工具,但还是建议谨慎行事.例如,如果剩余的 React 组件和库与 react@15.x.x 不兼容,您就不想安装 React 15.另请参阅 npm 的博文:为什么使用 SemVer?

我会把握机会.还有哪些工具?

仅举几例:

  • npm-check-updates 会做问题中最初提出的问题是:安装和更新所有依赖项的版本,而不管给定的范围限制如何.然而,对于这项工作,这将是最不推荐的工具.
  • updtr 会一一更新依赖,回滚到如果项目的测试失败,则使用以前的版本,这可能会在测试覆盖率良好的项目中节省时间.
  • npm-check 提供了一个交互式命令行界面,可让您轻松选择要更新的软件包.

这与 npm 5 有什么不同吗?

从主要版本 5 开始,npm 将自动创建一个 "package-lock.json",当一个shrinkwrap不存在时,它将填补指定依赖树的作用.更详细的描述可以在 package-locks 文档 中找到.一般来说,npm-shrinkwrap.json 是用来发布的,而 package-lock.json 是用来开发的.这就是为什么您还应该将package-lock.json"提交到存储库.

纱线怎么样?

Yarn,一个与 npm 兼容的依赖管理器,在使用时自动创建一个锁文件,其行为类似于 npm收缩包装.调用 yarn upgrade «package» 将更新一个依赖项到latest 标记中的版本,无论 package.json 或锁定文件中记录的版本范围如何.使用 yarn upgrade-interactive 还允许您有选择地将包升级到最新版本,这与 npm-check 不同.

$ yarn outdated纱线过时 v0.16.1包当前通缉最新巴贝尔 eslint 7.0.0 7.0.0 7.1.0柴 3.0.0 3.0.0 3.5.0在 0.84 秒内完成.$ yarn upgrade babel-eslint chai纱线升级 v0.16.1[1/4] 解析包...[2/4] 正在获取包...[3/4] 链接依赖...[4/4] 构建新鲜包...成功保存锁文件.成功保存了 2 个新的依赖项.├─ babel-eslint@7.1.0└─ 柴@3.5.0

I have an npm package with a fixed version that has an update.
Example package.json extract:

devDependencies: {
   "someFixedVersionPackage": "1.0.0", //1.1.0 is latest
   "anotherFixedVersionPackage": "2.3.2", //2.3.4 is latest
}

Does an npm command exist which installs the latest version of that package and updates the package.json, preferably all packages at once?

To be clear, I want the package.json snippet above to be updated to this, in addition to the packages themselves being updated:

devDependencies: {
   "someFixedVersionPackage": "1.1.0", //latest
   "anotherFixedVersionPackage": "2.3.4", //latest
}

Thank you.

解决方案

Why doesn't npm update work here?

As per the documentation on npm update:

This command will update all the packages listed to the latest version (specified by the tag config), respecting semver.

It will also install missing packages. As with all commands that install packages, the --dev flag will cause devDependencies to be processed as well.

Since your packages are defined with a fixed version, the update sub-command will not update those to respect semantic versioning. Therefore, it will only automatically update your packages if you specify a greater version range for each package. Note that it is actually typical in an npm project to specify a loose range version; one that is meant to avoid breaking changes but still leaves room for improvements and fixes.

Still, why shouldn't I fix dependency versions in my package.json?

But they are fixed because I wanted them so. After testing newer versions, I want to update them via command line as were created.

Having a list of dependencies with a fixed version does not mean that the dependencies installed will always be the same, because the dependencies of your dependencies will most likely also be defined with a version range. In order to keep track of a list of tested version-tagged dependencies, npm provides another mechanism: package locks.

Before version 5 of npm, you can create a "npm-shrinkwrap.json" file with the shrinkwrap command:

npm shrinkwrap

This command locks down the versions of a package's dependencies so that you can control exactly which versions of each dependency will be used when your package is installed.

Since npm 5, a "package-lock.json" is automatically generated when an npm operation modifies the "node_modules" tree or "package.json".

Rather than modifying package.json, either one of these package locks will override the default behaviour of npm install, installing dependencies with the versions specified by the lock, right when they were created or manually updated. With that out of the way, your dependencies can now be expanded without the risk of dependents installing untested package versions.

Shrinkwraps are used for publishing packages. To shrinkwrap a package:

  1. Run npm install in the package root to install the current versions of all dependencies.
  2. Validate that the package works as expected with these versions.
  3. Run npm shrinkwrap, add npm-shrinkwrap.json to git, and publish your package.

At this point, dependency versions can be loosened in your package.json (this will hopefully be done only once every major dependency update), so that later on they can be updated at will with npm update:

"devDependencies": {
   "someFixedVersionPackage": "^1.0.0",
   "anotherFixedVersionPackage": "^2.3.2",
}

The package-lock.json file can be used instead of a shrinkwrap, and is more suitable for reproducing a development environment. It should also be committed to the repository.

So how do I update my dependencies?

Calling npm update will do what's mentioned above: update dependencies while respecting semantic versioning. To add or upgrade a dependency in a package:

  1. Run npm install in the package root to install the current versions of all dependencies.
  2. Add or update dependencies. npm install --save each new or updated package individually to update the package.json, as well as the existing package locks ("package-lock.json" and "npm-shrinkwrap.json"). Note that they must be explicitly named in order to be installed: running npm install with no arguments will merely reproduce the locked dependencies.
  3. Validate that the package works as expected with the new dependencies.
  4. Commit the new package locks.

Moreover, here are a few tips for a smooth transition from a project with fixed dependencies:

  • If you haven't done so, expand the version range by adding a tilde (~) before the version specifier, or a caret (^). npm update will then attempt to install all patch revisions and minor revisions, respectively (major version 0 is a corner-case, see the documentation). For instance, "^1.0.0" can now be updated to "^1.1.0", and "~2.3.2" can be updated to "~2.3.4". Adding the --save or --save-dev flags will also update the "package.json" with the installed version (while keeping the previous range specifiers).

  • Run npm outdated to check which packages are outdated. Entries in red will be updated automatically with npm update. Other entries will require a manual intervention.

  • For packages with major version bumps, install that package with a version specification (e.g. npm install browserify@11.2.0 --save-dev). Further issues that may arise with the update will have to be handled manually. It usually helps to read the news feed or the release history on that package to further understand what has changed from previous versions.

This is not simple enough, is there another way to do this?

Before continuing, it is always worth mentioning that packages have a SemVer-compliant version definition for a reason. One should avoid blindly installing the latest version of every single package. Although such a full update can be done and tools are available for that, some caution is advised. For instance, you would not want to install React 15 if the remaining React components and libraries are not compatible with react@15.x.x. See also npm's blog post: Why use SemVer?

I'll take my chances. What other tools are there?

To name a few:

  • npm-check-updates will do what was initially asked in the question: install and update the versions of all dependencies, regardless of the given range constraint. This would be the least recommended tool for the job, however.
  • updtr will update dependencies one by one and roll back to the previous version if the project's tests fail, which may save time in projects with good test coverage.
  • npm-check provides an interactive command-line interface, which allows you to easily select which packages to update.

Is this any different with npm 5?

Since major version 5, npm will automatically create a "package-lock.json", which will fill the role of specifying the dependency tree when a shrinkwrap does not exist. A more detailed description can be found in the package-locks documentation. In general, npm-shrinkwrap.json is meant to be used when publishing, whereas package-lock.json is to be used in development. This is why you should also commit "package-lock.json" to the repository.

What about with Yarn?

Yarn, an npm-compatible dependency manager, creates a lock file automatically on use, which behaves similarly to the npm shrinkwrap. Calling yarn upgrade «package» will update one dependency to the version in the latest tag, regardless of the version range recorded in the package.json or the lock file. Using yarn upgrade-interactive also allows you to selectively upgrade packages to the latest version, not unlike npm-check.

$ yarn outdated
yarn outdated v0.16.1
Package      Current Wanted Latest
babel-eslint 7.0.0   7.0.0  7.1.0 
chai         3.0.0   3.0.0  3.5.0 
Done in 0.84s.
$ yarn upgrade babel-eslint chai
yarn upgrade v0.16.1
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 2 new dependencies.
├─ babel-eslint@7.1.0
└─ chai@3.5.0

这篇关于从命令行更新具有固定依赖项的 npm 包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆