Gulpの代わりにnpm-scriptsをタスクランナーとして使う

最近では当たり前のようにWeb制作時にGulpを使用していましたが、npm-scriptsを使用すれば、Node.js + npmのみで同等の環境を構築できることを知りました。いつ廃れるとも知らない、それに潰しの効かないGulpの学習にも疲れてしまったので、気分転換も兼ねてnpm-scriptsで開発環境を作ってみました。

npm-scriptsとは

Gulpでもお馴染みのpackage.json内にある「scripts」というフィールドに、シェルスクリプトやエイリアスコマンドを登録できます。これがnpm-scriptsです。

このファイルに記述したスクリプトは、npm run SCRIPTNAMEで実行が可能です。今回はこの「script」にGulpで定義していたタスクと同等のスクリプトを登録し、Gulpを介さずにビルドツールを構築することが目的です。

Gulpの問題点

Gulpの使用にあたって以下のような問題を抱えていました。

  • プラグインへの依存
  • 学習コストの高さ

1.プラグインへの依存

Gulpの魅力といっても良い豊富なプラグインですが、npmパッケージに依存しているプラグインも沢山あります。依存プラグインを使用している場合、依存元のパッケージにアップデートやAPIの変更などがあった時にプラグインが動かなくなる可能性があります。もちろんすぐにプラグイン開発者が対応してくれれば問題ないのですが、対応されるまで待たなくてはいけません。対応が遅い(あるいは更新が止まってしまう)と業務にも支障が出てきます。

2.学習コストの高さ

Gulpの学習は応用が利きません。厳密に言えばJavaScriptを書くのでJavaScriptの勉強にはなるのかもしれませんが、内容的には他の仕事に応用ができたという事例は個人的にはありません。
さらにnpmパッケージに依存しているプラグインを使用していると、プラグインのドキュメントと依存パッケージのドキュメント両方を参照しなければいけない場面に遭遇します。英語のドキュメントも多いので、それらを行ったり来たりするのはかなり疲れます。

npm-scriptsを使用するメリット

ではGulpと比べてどこが良いの?というところですが、下記のようなメリットがあります。

  • Gulpを介さずnode_modulesを直接実行が可能
  • 基本的にpackage.jsonのみで完結
  • Gulpの学習コストが不要

1.Gulpを介さずnode_modulesを直接実行が可能

node_modulesを直接実行できるということは、パッケージ依存のプラグインの依存元をGulpを介さずに実行できるということです。これはプラグインへの依存からの脱却を意味します。あたらしい機能やAPIもすぐさま試すことができ、動かなくなるということもありません。

2.基本的にpackage.jsonのみで完結

「基本的に」と書いたのは、タスクを外部ファイルに抜き出して、それを参照できるためです。しかし1、2人で完遂できる規模のWebサイト制作においては、ほとんどがpackage.json内で完結できるのではないかと思っています。

3.Gulpの学習コストが不要

これは表題の通りです。

npm-scriptsのデメリットと解決策

つづいてデメリットとその解決策について見ていきたいと思います。使用してみて実感しているデメリットとしては下記の2つがあります。

  • クロスプラットフォームでない
  • 可読性が悪い

1.クロスプラットフォームでない

npm-scriptsはShellに依存しているためOSXやLinuxなどのUNIX系とWindows間でクロスプラットフォームの問題が生じます。しかしそれらもnpmパッケージを使用することで問題を回避することができます。例えばUNIX系とWindowsでコマンド名が違うような場合を例としてあげます。

cpx

フォルダ構造を維持したまま指定の場所にコピーしたい場合がありますよね。そのような処理をするにはcpがありますが、WindowsではCOPYといい、名前が異なるようです(当方Macユーザーなので未使用)。このような時にnpmパッケージが力を発揮します。cpxというパッケージがありますので、こちらを下記のように使用すれば環境に依存することなく動作します。

cpx ./src/**/{*.js,*.css} ./dist

2.可読性が悪い

ワンライナーで記述するので可読性はどうしても悪くなります。ですので、私は単一機能ごとにタスクを分けて書くことを意識しています。まとめて実行したい場合は複数を組み合わせて呼び出して使用しています。

"scripts": {
     "css:prefix": "postcss --use autoprefixer -b 'last 2 versions' ./dist/**/*.css -d ./dist",
     "css:sass": "node-sass ./src/**/*.scss ./dist",
     "build:css": "npm-run-all -s css:sass css:prefix"
}

上記のようにベンダープリフィックスの付与をするタスクとsassのコンパイルのタスクを用意しておき、buildタスクで2つのタスクを呼び出しています。
またbuildタスクにあるnpm-run-allというのは、npm-scriptsに定義した複数のタスクをまとめて実行できるものです。-sは同期で-pだと非同期で実行されます。今回の場合、sassのコンパイルが完了してからプリフィックスを付与したいので同期で実行しています。

まとめ

以上、簡単ではありますがnpm-scriptsに興味を持ってたどり着いた方向けのエントリーでした。これを入口として本腰を入れて使ってみようと思った方は、以下のエントリーが非常に充実した内容になっていて、私も熟読して勉強になったので一度目を通すことをオススメします。

またpackage.jsonの設定の紹介は一部となってしまいましたが、githubに公開していますので良ければご確認ください。

プロジェクトによってはGulpを使用した方が良い場面もあると思いますし、ケースバイケースで使い分けるのが良いのではないかと現時点では思っています。