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.json の engine では 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 で削除されたそうだ。

また、 .npmrc に engine-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.json の engine の指定を見て満たしていない場合はエラーとなる。また、 yarn install に --ignore-engines オプションを与えるとエラーとせず無視するようにすることもできる。

yarn install | Yarn

まとめ

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

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

となるようだ。

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


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