HogeFugaHogera

IT系の備忘録とか、他徒然なるままに

Windows Azure上でのnpm

 ローカル上にnpmでパッケージをインストールした場合、それをAzure上に上げるにはどうすればよいのか? 答えは、Microsoftの公式ドキュメントにあります。

この記事では、Azure Websitesにおいて、npmでインストールしたモジュールをアップロードする方法を簡単に示します。

前提

環境は、以下となります。

f:id:einstee:20150215230629j:plain

デプロイ方法がgitのみなため、他の方法(FTP等)での挙動がどうなるのかは分かりません。 多分、動くとは思いますが...。

方法1. localのnode_modules ディレクトリを、Azure側にコピーする

 ローカル側アプリケーション構成ディレクトリのルートにあるnode_modulesディレクトリを、Azure側にpushします。利点としては、ローカル側とまったく同じモジュールが使用できる事です。 問題としては、node_modules内のnpmでインストールされたモジュールが、必ずしもJavaScriptだけで書かれた物だけではないという事です。すなわち、モジュールによっては、ローカル側プラットフォームに依存するバイナリイメージを使用している物もあります。
 私の環境の場合、ローカル側はMac OS Xなので、ここでビルドされたバイナリイメージはAzure側で使用できません。よって、インストールしたモジュールの依存モジュールの依存モジュールの...依存モジュール全てがJavaScriptのみで動いていると確信できない限り、この方法は現実的ではありません。
ただし、ローカル側がWindows開発環境なら、その限りではないようです。

  • 日本語版資料から
    Azure Cloud Services は、アプリケーションの一部としてデプロイされている node_modules フォルダーに依存するので、インストールされたモジュールの一部として含まれるネイティブ モジュールはすべて、Windows 開発システムでインストールおよびコンパイルされている限りクラウド サービスで動作します。
  • 原文英語から
    Run npm install on a Windows machine that has all the native module's prerequisites installed. Then, deploy the created node_modules folder as part of the application to Azure Websites.
    [訳] ネイティブモジュールに必要なものがインストールされたWindowsマシンでnpm installを行う。そして、アプリケーションの一部として、作製されたnode_modules フォルダをAzure Websitesにデプロイする。

方法2. package.json or npm-shrinkwrap.jsonを、Azure側にコピーする

まず、標題の二つのファイルの簡単な説明です。

  • package.json: npm install -seve等でインストールされたパッケージの情報が含まれ、依存モジュールは含まれない。記載パッケージのバージョン指定は緩いものとなっている(モジュールによって、許されるバージョンの範囲が異なる)。
  • npm-shrinkwrap.json: 依存モジュールも含めた全てのインストールされたパッケージの情報が含まれる。また、記載パッケージのバージョンは、インストールされたものが指定される。

これらファイルをgit等でazure側にデプロイすると、自動でモジュールがインストールされます。デプロイするファイルによる挙動の違いは以下となります。

  • package.json: ローカル側と異なるバージョンのモジュールがインストールされる可能性がある(記載パッケージのバージョン指定範囲に依存する)
  • npm-shrinkwrap.json: ローカル側と同一バージョンのモジュールがインストールされる。

モジュールのバージョンに厳密さを求めるならnpm-shrinkwrap.jsonをデプロイするべきでしょうし、個々の目的に合ったファイルを使用すべきです。

方法2. Q. プラットフォームに依存するバイナリイメージを使用するモジュールはどうなるのか?

A. 基本的にインストールに失敗します。
これは、この手のモジュールをインストールする際によく使われるPythonおよびnode-gypが、azure上に用意されていない為です。 例外的に、JSDOM、MongoDB などの、オプションとしてバイナリイメージを使用する場合は、動作することもあるようですが。

では、絶対にこの手のバイナリイメージを含むモジュールを使用できないかといえば、答えはNoとなります。
方法1.の日本語版資料を再度引用します。

  • 日本語版資料から
    Azure Cloud Services は、アプリケーションの一部としてデプロイされている node_modules フォルダーに依存するので、インストールされたモジュールの一部として含まれるネイティブ モジュールはすべて、Windows 開発システムでインストールおよびコンパイルされている限りクラウド サービスで動作します。

すなわち、Windows環境下でバイナリイメージをコンパイルして、それをazure側node_modulesフォルダの該当する箇所に置いてしまえばいいのである。

もっとも、私のようにMac環境しか手元にない人間にとってはどうしようもないのだが...。 しかし、原文資料を読むと、こんなことが書かれている。

  • Azure Websites can be configured to execute custom bash or shell scripts during deployment, giving you the opportunity to execute custom commands and precisely configure the way npm install is being run. For at tutorial on how to do this, see Custom Website Deployment Scripts with Kudu.
    [訳] Azure Websitesは、デプロイメント中に手製のbash or shellスクリプトの実行を設定できるので、カスタムコマンドを実行して、まさにnpm installが走られているように構成できる。これを行う為のチュートリアルは、こちら: Custom Website Deployment Scripts with Kudu (リンク切れ)

うまくやれば、azuru側でコンパイルする事も可能なのかもしれない。リンク切れなので、果たして実際の内容がどのような物だったのかは分からないが。