現代の開発者として、私たちは開発の速度と効率を改善するためのますます多くのツールにアクセスできます。 おそらく、Node.jsやその他のバックエンドJavascriptツールの人気が高まっている最も影響力のある要因の1つは、開発のすべての段階で使い慣れた構文を使用できることです。

たとえば、タスクランナーは、開発プロセスのありふれた側面を自動化することを唯一の目的とするプログラムです。 Grunt.js Gulp webpack など、非常に便利なさまざまなJavascriptタスクランナーとビルドツールがあります。 強力で知ることは非常に貴重ですが、それほど注目されないが同様に動作し、深く知ることも同様に価値のある別のツールがあります。npmにはスクリプト機能が組み込まれています。

npmスクリプトを使用して開発ニーズをサポートするさまざまな方法を見てみましょう。

Package.json

Nodeのすべてのプロジェクトには、プロジェクトに関するメタデータを含むpackage.jsonファイルがあります。 このファイルには、タイトル、説明、バージョン、依存関係などが含まれています。 このファイルの主な目的は、npmでプロジェクトを公開できるようにすることです。 誰かがnpmから私たちのプログラムをインストールしたいとき、彼らのシステムは私たちが正しく実行するために依存している他のプログラムを知る必要があります。 また、プログラムの動作と構成について特定のことを知る必要があります。 package.jsonファイルからこのすべての情報を取得します。

典型的なpackage.jsonファイルは次のようになります。

{
  "name": "Crispy",
  "version": "1.0.0",
  "description": "Cooked to perfection!",
  "main": "index.js",
  "scripts": {
    "test": "mocha"
  },
  "author": "AlligatorIO",
  "license": "ISC",
  "dependencies": {
    "ws": "^3.3.2"
  },
  "devDependencies": {
    "webpack": "^3.8.1"
  }
}

ご覧のとおり、これは、プロジェクトに関連する情報を含むJSONオブジェクトを含むファイルにすぎません。

この情報の1つは、scriptsセクションです。 これらのスクリプトは、開発および公開のライフサイクル全体のさまざまな時点でトリガーされるコマンドです。 最も一般的なnpmスクリプトの2つは、startスクリプトとtestスクリプトです。 前の例では、開始スクリプトが定義されていないことに気付くでしょう。 これは、npmの開始スクリプトのデフォルト値がnode server.jsであるためです。 つまり、独自のカスタム開始スクリプトを定義しない場合、コマンドラインにnpm startと入力すると、server.jsという名前のファイルが自動的に検索され、見つかった場合はそのファイルがNodeで実行されます。

また、testスクリプトの値は単に「mocha」であることに注意してください。 Mocha は一般的なJavaScriptテストツールキットであり、インストールすると、コマンドラインでmochaコマンドを使用するだけで実行できます。 この場合、テストスクリプトはそれ以上のことは何もしていません。

さまざまなユースケースをカバーするさまざまなnpmスクリプトがありますが、現在私たちが最も関心を持っているのは、これらのスクリプトを使用して、新しいプロジェクトの開発中に私たちの生活を楽にするさまざまな方法です。

ライフサイクルを理解する

npmスクリプトの能力を解き放つための最初の鍵は、スクリプトを実行するときにnpmが何をしているのかを理解することです。 最初に行うことは、 package.json ファイルをチェックして、そのスクリプトの値を定義したかどうかを確認することです。 持っていることがわかった場合は、スクリプトの他の2つのバージョンを探します。 「前」バージョンと「後」バージョン。 これらのいずれかが見つかった場合は、指定されたスクリプトに関してそれらを実行します。

例:

{
  "scripts": {
    "prestart": "node loadJaw.js",
    "start": "node Gator.js",
    "poststart": "node bite.js"
  }
}

これがnpmがpackage.jsonファイルで見つけたものである場合、スクリプトはprestartstartpoststartの順に実行されます。 これをトリガーするために行うのは、コマンドラインにnpm startと入力することだけです。 これは、プライマリアクションの直前または直後に何かを実行する必要があるさまざまな状況で非常に役立ちます。 開発では、データベースのローカルコピーを起動するために接続するか、ファイルをバンドルする必要がある場合があります。エラーを回避するために、サーバーを起動する前にこれらの処理が行われることを確認する必要があります。

スクリプトを適切に設定すると、コマンドnpm startを実行するだけで、すべてのニーズを適切な順序で処理できるようになります。

開発モードと本番モード

npmスクリプトを利用する最も便利な方法の1つは、グローバルプロセス変数を介して任意のノードプログラムでアクセスできるノードのNode_ENV変数の値を変更することです。 process.env.Node_ENVを参照するだけで、その値を見つけることができます。

function getEnvironment(){
  return process.env.Node_ENV;
}

getEnvironment(); // returns 'production';

多くのフレームワークは、Node_ENV変数の値を使用して、開発モードで実行するか本番モードで実行するかを決定します。 違いは、多くの場合、本番モードはパフォーマンス用に最適化されているのに対し、開発モードはデバッグ用に最適化されていることです。 Node_ENV変数の値に応じて異なる構成のプログラムを作成することにより、この共通のメカニズムを独自のプロジェクトで利用できます。

たとえば、訪問者をサイトに記録したいとします。 本番モードでは、後で参照できるように、新しい各訪問者のIPアドレスをログファイルに記録したい場合があります。 開発モードでは、トラフィックをリアルタイムで分析してバグを整理している可能性があるため、新しい訪問者に関する情報を別のファイルに記録するとともに、トラフィックをコンソールに記録して、発生を監視できるようにします。 これは次のように簡単です。

const fs = require('fs');
const inDevelopmentMode = process.env.Node_ENV === development;

function newVisitor(ip){
  let logMessage = "New Visitor IP: " + ip;

  if(inDevelopmentMode){
    fs.writeFile("development_log.txt", logMessage, (err) => {
      if(err) throw err;
    });
    console.log(logMessage);
  }
  else{
    fs.writeFile("production_log.txt", logMessage, (err) => {
      if(err) throw err;
    });
  }
}

ここでは、fsモジュールを使用してファイルシステムと対話しています。 Node_ENV変数を参照して、開発モードであるかどうかを判断し、そうである場合は、development_log.txtファイルとコンソールの両方にログを記録します。 本番モードの場合は、コンソールにログを記録せずに、production_log.txtファイルにログを記録するだけです。

しかし、実際にNode_ENV変数を変更するにはどうすればよいでしょうか。 1つの方法は、npmスクリプトを使用することです。 package.json ファイル:

{
  "scripts": {
    "start": "SET Node_ENV=development& node server.js",
  }
}

構文は少しおかしいように見え、一見するといくつかの質問を思い起こさせるかもしれません。 これがなぜこのように行われるのかについての説明です。 これを行おうとするときに注意すべき重要であるが予測できないことがいくつかあります。

  • Node_ENV変数を、それと相互作用することを意図したステップ以外のステップで設定すると、エラーが発生する可能性があります。 これは、npmスクリプトが実行されるたびに、それが別の「プロセス」と見なされるためです。 prestartスクリプトのNode_ENV値を変更した場合、startスクリプトプロセスには引き継がれません。 したがって、server.jsファイルで操作する場合は、startスクリプトで変更する必要があります。

  • LinuxとWindowsが変数の変更を処理する方法にはわずかな違いがあります。 Linuxでは、SETコマンドを省略して、Node_ENV=development& node server.jsを使用するだけです。 Windowsでは、SETコマンドを使用して変数を変更する必要があります。

  • このコード行でdevelopment&の間にスペースがないことを確認することが重要です。スペースがないと、空白が変数の値の一部になり、falseprocess.env.Node_ENV === "development"をチェックする場合。

もちろん、LinuxとWindowsが環境変数を設定する方法の違いは、チームが両方のオペレーティングシステムからのプロジェクトに取り組んでいる場合、非互換性につながる可能性があります。 これを処理する方法はいくつかあります。 コマンドを実行する前にプログラムが実行されているオペレーティングシステムを判別しようとするcross-envなどのスクリプトまたはモジュールを使用するか、オペレーティングシステムごとに異なるnpmスクリプトを使用してそのままにすることができます。どちらを使用するかを覚えておくのは開発者次第です。 どちらの方法も有効ですが、さまざまなコンテキストで同様のことを行う代替のnpmスクリプトを作成するにはどうすればよいでしょうか。

任意のスクリプト

幸いなことに、npmは、独自のカスタム任意のスクリプトを定義できるようにすることで、これを行うための組み込みの方法を提供します。 これらのスクリプトには任意の名前を付けることができ、npmは期待どおりにスクリプトを実行します。 指定された名前の前に「pre」と「post」を追加することにより、トリガーされたときにスクリプトのすべてのライフサイクルバリエーションを実行しようとします。 これにより、開発中に使用できるカスタムスクリプトをいくつでも使用できます。 重要な違いは1つだけです。それは、コマンドラインからスクリプトをトリガーする方法にあります。

ネイティブにサポートされているすべてのnpmスクリプトに対して、npm <script-name>と入力します。任意のスクリプトをトリガーするには、npm run <script-name>を使用する必要があります。 それが唯一の違いです。 Linuxユーザーが操作するために変更された開始スクリプトが必要な場合は、開始スクリプトからSETコマンドを省略したスクリプトを作成し、選択した名前を付けることができます。

また、ローカルのMongoDBインスタンスを起動するためのカスタムスクリプトが必要な場合は、次のようにすることができます。

{
  "scripts": {
    "start": "SET Node_ENV=development& node server.js",
    "mongo": "mongod --dbpath=./pathToDatabase/db"
  }
}

これで、npm run mongoを使用してデータベースを起動できます。

任意のスクリプトは、さまざまなコマンドシーケンスを自由にトリガーするのに最適です。 たとえば、次のようにします。

{
  "scripts": {
    "test": "mocha",
    "start": "SET Node_ENV=development& node server.js",
    "mongo": "mongod --dbpath=./pathToDatabase/db",
    "launch": "npm test && npm run mongo && npm start",
  }
}

ここに、テスト、mongo、および開始スクリプトをこの順序でトリガーする起動スクリプトがあります。 スクリプトでconcurrentlyなどのパッケージを使用して、アクションを同時に実行することもできます。

{
  "scripts": {
    "start": "concurrently \"node grip.js bacon\" \"node bite.js bacon\""
  }
}

最終的な考え

これを読んで、npmスクリプトを使用して開発ワークフローを支援する方法についてのアイデアが得られたと思います。 個人的には、startスクリプトで本番環境をトリガーし、任意のdevスクリプトを作成して開発環境をトリガーすることを好みます。 このように、準備ができたら package.json で本番モードに戻すために他に何も変更する必要はありません。これは、npm startを使用するのと同じくらい簡単です。