近年のWeb制作の現場では作業の自動化が流行っています。「Gulp」や「Grunt」に代表されるタスクランナーにより人力の作業を減らすことができ、生産効率や品質の向上につながります。どちらもNode.jsのモジュールとして動作するタスクランナーですが、実はこれらのタスクランナーを使わずとも、Node.jsインストール時に付属するnpm(Node Package Manager)を使用すれば、タスク処理が実現できます。

npmとはNode.jsのモジュールを管理するためのツールであり、タスク処理にはnpmの機能のnpm-scriptsを使用します。 npm-scriptsは、Gulpなどのタスクランナー自体の仕様変更によりプロジェクトで使用していた他のモジュールが使用できなくなるなどの煩わしさが無く、安定した技術と言えます。本記事はnpm-scriptsを使ったタスク実行環境が構築できることを目標に解説します。

そもそもnpm-scriptsとは何か?

npm-scriptsとは、package.jsonファイルに記述可能なシェルスクリプトのエイリアスです。エイリアスとはコマンド名を別のコマンド名に置き換えることです。以下のnpm-scriptsはHello world!!を表示させるコマンドのエイリアスを作成する例です。

{
  "scripts": {
    "hoge": "echo 'Hello world!!'"
  }
}

上のようにpackage.jsonに記述しておけば以下のコマンドでエイリアスを実行可能になります。これがnpm-scriptsです。

bash1

※上記の例ではechoコマンドを使用していますが、OS特有のコマンドを使用した場合、環境によって動作しない場合があります。UNIXのコマンドやWindowsのコマンドを使用する際は気をつけましょう。

npm-scriptsの使い方

SassTypeScriptのビルドを例にnpm-scriptsの使い方を更に詳しく解説します。

1. モジュールのインストール

SassとTypeScriptのビルド用モジュールをそれぞれインストールします。プロジェクト単体で使用するモジュールとしてインストールしたいのでオプションに--save-devを指定します。

npm install node-sass --save-dev
npm install typescript --save-dev

2. モジュールのコマンド実行

インストールが完了したのでnode-sassのコマンドを実行してヘルプを表示させましょう。

bash2

コマンドが見つからずエラーが表示されました。--save-devでインストールしたモジュールのコマンドは、グローバルなコマンドとして実行することができません。npm-scriptsとして記載することで実行可能です。

{
  "scripts": {
    "scss:help": "node-sass --help"
  }
}

追加したscss:helpコマンドを実行してみます。

bash3

無事node-sassのヘルプが表示されました。このようにモジュールの機能はGulpやGruntを介せずともnpm-scriptsから使用可能です。

3. scriptsの整理術

npm-scripts記述においてのちょっとした整理術を紹介します。まず実際にwatchするためのnpm-scriptsをpackgage.jsonに記載していきます。

{
  "scripts": {
    "watch:scss": "node-sass ./scss --output ./css -w",
    "watch:ts"  : "tsc -w"
  }
}

SassとTypeScriptをそれぞれwatchするためのコマンドが完成しました。実行するためには以下のコマンドを実行します。

npm run build:scss & npm run build:ts

シェルスクリプトは&で接続することで並列処理、&&では直列処理を行うことができます。しかし、コマンドを接続したことで冗長になってしまいました。使用する上で少々不便なので、このコマンドもnpm-scriptsへ追加してしまいます。

{
  "scripts": {
    "watch"     : "npm run watch:scss & npm run watch:ts", // <= 追加
    "watch:scss": "node-sass ./scss --output ./css -w",
    "watch:ts"  : "tsc -w"
  }
}

以下のように短いコマンドでSassとTypeScriptのwatchを同時に実行可能になりました。

npm run watch

同じようにビルドコマンドを追加して一通り完成です。buildとwatchの行いやすい整理されたnpm-scriptsができあがりました。

{
 "scripts": {
    "build"     : "npm run build:scss && npm run build:ts",
    "build:scss": "node-sass ./scss --output ./css",
    "build:ts"  : "tsc"
    "watch"     : "npm run watch:scss & npm run watch:ts",
    "watch:scss": "node-sass ./scss --output ./css -w",
    "watch:ts"  : "tsc -w"
  }
}

4. おまけテクニック

npm-scriptsにはユーザーのアクションをきっかけに自動で実行してくれるコマンドがいくつか用意されています。その中のpostinstallコマンドを使用することで、より効率良い開発環境構築が行えるようになるので少しだけ紹介します。

postinstallコマンドとはnpm installコマンドの終了時に実行されるコマンドです。

{
 "scripts": {
    "build:ts"   : "tsc",
    "postinstall": "npm run build:ts"
  }
}

この例では、開発者がnpm installを実行してモジュールのインストールが終了したタイミングでbuild:tsコマンドを実行してくれます。他にも、TypeScriptの型定義ファイルのインストールコマンドをpostintallに追加しておくといった事もできます。postinstallコマンドを用意しておくことで、ちょっとした手間を解消できるのでオススメです。

GulpやGruntは使うべきではないのか?

npm-scriptsを使うことでGulpやGruntを介さずにタスクの実行ができることがわかりました。ではGulpやGruntはもう使うべきでは無いのでしょうか? そうとは言えません。npm-scriptsのみを使用する場合のメリットとデメリットを挙げます。

メリット

  • GulpやGruntの仕様変更に振り回されない
  • 使用可能なnpmモジュールが豊富

デメリット

  • 複雑なタスクは行いづらい
  • シェルスクリプトの知識が必要

複雑なタスクを必要としないプロジェクトであればnpm-scriptsのみで完結しますが、プロジェクトによってはGulpを使用せざる終えない場合もあります。しかし、その場合もnpm-scriptsは活用できます。Gulpを例に解説します。下記の例は前章で作成したpackage.jsonのタスクをGulpで置き換えたものです。

{
  "scripts": {
    "build"     : "gulp build",
    "build:scss": "gulp build:scss",
    "build:ts"  : "gulp build:ts"
    "watch"     : "gulp watch",
    "watch:scss": "gulp watch:scss",
    "watch:ts"  : "gulp watch:ts"
  }
}

一見、エイリアスを介すことで煩わしくなったように思えますが、いくつか利点があります。

  1. gulpコマンドをグローバルにインストールする必要が無い
  2. gulpコマンドのバージョンがプロジェクト毎に固定されるため、Gulpの大きな仕様変更にも左右されない
  3. npmの知識だけあればタスクが実行できる

このように併用することで、より効率の良い環境をつくる事が可能です。Gruntの場合も同様です。

終わりに

意外と知られていないnpm-scriptsの使い方ですが、知っていると非常に役立ちます。筆者もnpm-scriptsでタスクは完結させるように心がけていますが、シェルスクリプトの知見も深まるのでオススメです。npmモジュールの流行り廃りは早いですが、npm自体はしばらくは廃れることもないはずなので、みなさんも是非この機会に触れてみてください。