のこのこかずのこ

10年エンジニアやってるけどいまだになんもわからん

JavaScriptの言語拡張 Flow インストール時のエラー Error: spawn Unknown system error -86 に対処する

Flowとは

Flow: A Static Type Checker for JavaScript | Flow

JavaScriptコードに型情報を付与するための言語拡張。最近ではTypeScript一強でFlowが選択されることはほぼないと思いますが、ちょっと試しに動かしてみる必要があったためインストールしました。その際にエラーで少し躓いたので、その備忘録です。

インストール時のエラー

公式サイトに従ってnpmで flow-bin をインストールしましたが、以下のようなエラーとなりました。 (プロジェクトローカルにインストールしているので、npxを使っています。)

% npm install --save-dev flow-bin
% npx flow --version
node:internal/child_process:420
    throw errnoException(err, 'spawn');
    ^

Error: spawn Unknown system error -86
    at ChildProcess.spawn (node:internal/child_process:420:11)
    at spawn (node:child_process:733:9)
    at Object.<anonymous> (/Users/ayaka/study/JavaScript第7版/node_modules/flow-bin/cli.js:14:3)
    at Module._compile (node:internal/modules/cjs/loader:1198:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1252:10)
    at Module.load (node:internal/modules/cjs/loader:1076:32)
    at Function.Module._load (node:internal/modules/cjs/loader:911:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:22:47 {
  errno: -86,
  code: 'Unknown system error -86',
  syscall: 'spawn'
}
対処法

最初は、Node.jsのバージョンが対応していないのかと思い、nodenvでバージョンを v16 に下げてみたりしましたが、エラーは解消しなかったです。

chatGPTくんに聞いたところ…

Flowのバイナリが現在のシステムと互換性がないことが原因である可能性があります。特に、Apple Silicon(M1、M2など)のMacでこの問題が発生することがあります。

使用しているのはM2チップのMacだったので、ターミナルをRosettaモードで起動し、Intelベースで実行したところ、エラーが解消されました。

参考: Mac に Rosetta をインストールする必要がある場合 - Apple サポート (日本)

Rosettaモードでターミナルを起動する方法
  1. まず、ターミナルを一旦終了する。
  2. Finderでアプリケーションフォルダ > ユーティリティ に移動する。
  3. ターミナルアプリを右クリックして「情報を見る」を選択し、「Rosettaを使用して開く」にチェックを入れる。
  4. ターミナルを起動すると、Rosetta のインストールの案内がされるので、インストールする。
    Rosettaのインストール案内

ターミナルが開いたら、Rosettaモードで起動しているか確認してみる。「x86_64」になってればOK。

% uname -m
x86_64

npx flowのエラーが解消されました!

% npx flow --version
Flow, a static type checker for JavaScript, version 0.241.0

ちなみに、Node.jsのバージョンはv20.11.1で特に問題なく動いています。

参考にさせていただきました: 【重要】MACのRosettaの確認方法と対応アプリケーションについて解説 | よっしーノート

Flowの動作チェック

テストしたいJavaScriptファイルの先頭に // @flowを記述します。わざとエラーが出るようなコードにしています。

// @flow
function foo(x: ?number): string {
  if (x) {
    return x;
  }
  return "default string";
}

キャッシュクリアしてからFlowを実行したところ、動作してエラーを検出してくれました!

% npx flow stop
% npx flow start
% npx flow            
Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ test.js:4:12

Cannot return x because number [1] is incompatible with string [2].
...(略)

とりあえず動かせるようになって良かったですが、Flowはもう新たに選択されることはないんだろうな〜と思いました😌