package.json の engine について npm と yarn の挙動の違い

発端

yarn でインストールしていたプロジェクトのライブラリバージョンを上げようとしたら、以下のエラーが出てインストールできなかった。[1]

$ yarn install
yarn install v1.13.0
[1/5] 🔍  Validating package.json...
[2/5] 🔍  Resolving packages...
[3/5] 🚚  Fetching packages...
error bellajs@7.5.0: The engine "node" is incompatible with this module. Expected version ">= 7.6". Got "6.17.0"
error Found incompatible module
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

たしかに package.jsonengine では node 6.x 系を指定しており、まぁエラーが出ること自体は問題ない。

ただ、これを npm install してみたところ、エラーとならずインストールできてしまった。

調べてみた

この挙動の違いが気になったので、ちょっと調べてみたところ、以下ということがわかった。

npm の場合

npm-package.json | npm Documentation

engines
Unless the user has set the engine-strict config flag, this field is advisory only and will only produce warnings when your package is installed as a dependency.

engineStrict
This feature was removed in npm 3.0.0
Prior to npm 3.0.0, this feature was used to treat this package as if the user had set engine-strict. It is no longer used.

npm の方では、 engine の指定は engineStrict を併用しないとあくまでも warning に留まるのみ。加えて engineStrict は npm 3.0.0 で削除されたそうだ。

また、 .npmrcengine-strict=true と設定しておくことで、エラー扱いにすることもできるそう。

project毎のnpmコマンドをいい感じにするnpmrc & config達 - Qiita

$ cat .npmrc
engine-strict=true

$ npm install
...omitted...
npm ERR! node v6.17.0
npm ERR! npm  v3.10.10
npm ERR! code ENOTSUP

npm ERR! notsup Unsupported engine for bellajs@7.5.0: wanted: {"node":">= 7.6"} (current: {"node":"6.17.0","npm":"3.10.10"})
npm ERR! notsup Not compatible with your version of node/npm: bellajs@7.5.0
npm ERR! notsup Not compatible with your version of node/npm: bellajs@7.5.0
npm ERR! notsup Required: {"node":">= 7.6"}
npm ERR! notsup Actual:   {"npm":"3.10.10","node":"6.17.0"}

たしかにエラーとなった。

yarn の場合

package.json | Yarn

The engines specify versions of clients that must be used with your package. This checks against process.versions as well as the current version of yarn.

上述のように package.jsonengine の指定を見て満たしていない場合はエラーとなる。また、 yarn install--ignore-engines オプションを与えるとエラーとせず無視するようにすることもできる。

yarn install | Yarn

まとめ

package.jsonengine の指定について、インストールされるパッケージがその要件を満たさない場合の挙動は、

  • npm の場合はデフォルトは warning 止まり。エラーとはならない。 .npmrc でエラーとすることもできる。ただし engineStrict は npm 3.0.0 以降削除されるとのこと。
  • yarn の場合はデフォルトはエラー。オプションで無視することもできる。

となるようだ。

普段 npm 文化圏で生活していないこともあって、 yarn は速い npm でしょ、くらいの認識でいたのでちょっとハマってしまった。


  1. 使っている node のバージョンが古いのは見逃してください…古いから気づいた、ということもあり。 ↩︎