開発環境、テスト環境、ステージング環境、本番環境・・・その他にも沢山のプログラムの実行環境が存在しますが、全てを設ける必要はないのですが、開発環境と本番環境の2つぐらいは最低設けていると思います。
そんな環境を全て同一に保つというのもなかなかの運用コストの掛かる作業になるのですが、dockerのコンテナをうまく使って同一環境にするという手もありますが、本番環境において、特定のサーバーホスティング環境を使わざるを得ない時に、dockerコンテナが適用できないケースもあります。
そんな時に、バージョンによる挙動の違いを把握していないと、無駄な調査時間に時間を取られるということはすくなくありません。
今回はポーリング処理において、NodejsのSocketIOは非常に高品位なスペックを持っていると、色々なサーバーエンジニアから聞くことが多いので、PythonやRubyではなく、Nodejsを使うようにしているのですが、開発環境の移設を行った際にバージョントラブルが発生したので、その対処方法を含めた備忘録を記録しておきます。
環境について
今回は、開発環境に構築してあるdockerコンテナの中で発生しました。
とある2つのプロジェクトがあり、プロジェクトAと同様のポーリング処理をプロジェクトBにコピーした時にその事象は発生しました。
プロジェクトAでは、NodejsのSocketIOで構築されたrunコードがあり、それをプロジェクトBにファイルコピーして、起動した時に以下のようなエラーが発生しました。
$ nodejs socket.test.js
/usr/local/lib/node_modules/socket.io/node_modules/debug/src/node.js:132
let val = process.env[key];
^^^
SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:374:25)
at Object.Module._extensions..js (module.js:417:10)
at Module.load (module.js:344:32)
at Function.Module._load (module.js:301:12)
at Module.require (module.js:354:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (/usr/local/lib/node_modules/socket.io/node_modules/debug/src/index.js:9:19)
at Module._compile (module.js:410:26)
at Object.Module._extensions..js (module.js:417:10)
ポイントは、"let"命令が、"SyntaxError"になっている箇所ですが、ES6の命令がnodejsで対応していないバージョンという事が分かります。
ちなみに、何故プロジェクトBでエラーが出るのに、同じ環境で動いているプロジェクトAではエラーが出ないのかが不思議ですよね?
プロジェクトAは、node-modulesがローカル環境にインストールされていて、プロジェクトBでは、グローバル環境にインストールされていました。
この後、グローバルよりもローカルを優先するnodejsの特性から、プロジェクトAとプロジェクトBのsocketIOのバージョンが違うというのが答えであることにたどり着きます。
原因について
それぞれのsocket.ioフォルダにある、"package.json"というファイルを見ると一番下の行に"version"が書かれているので比べてみると
プロジェクトA : 2.1.1
プロジェクトB : 2.2.0
マイナーバージョンの違いですが、ver2.1はES5対応で、ver2.2よりES6対応になっていることがわかりました。
https://socket.io/
https://socket.io/blog/socket-io-2-0-1-2-0-2-and-2-0-3/
socketioの本家サイトでバージョン毎の仕様が確認できます。
※面倒くさいので今回は内容は詳細に読み込んでいません・・・
対策について
どちらかと言うと下位互換を優先させたいので、今回は旧バージョンを使用したいと思い、下記コマンドでグローバル環境に対して古いバージョンのsocketioをインストールして事なきを得ました。
$ npm install -g socket.io@2.1.1
任意バージョンで固定インストールしたい場合@マークを付けてバージョンを入れるだけで簡単に下位バージョンの登録ができるので、この方法は覚えておいたほうが良さそうですね。
0 件のコメント:
コメントを投稿