はじめに
こんにちは、UNIBA の monpy です。
今回は npm script
の話です。 npm
の資産を利用してフロントエンドのソースコードをビルドしている人向け。
私は grunt
, gulp
, webpack
を経て npm script
でフロントのコードをビルドするという運びとなりました。
理由としては、grunt
, gulp
, webpack
のパッケージが邪魔な気がした&疲れた + npm script
信者からの圧倒的圧力
npm script
package.json
の scripts
フィールドにコマンドが書けます。
node_modules/.bin/
の中のエイリアスを直接利用できます。普段使っているコマンドも使用可能。
ちなみにカレントディレクトリは package.json
があるフォルダとなります。
その他細かいルールなど
Grunt/Gulpで憔悴したおっさんの話 このページが非常に参考になったりします。
あとは 公式を見るのが良い
サンプル
ここに用意した。
このビルドの目的は
- 複数の js, css をビルドする
- minify をさせる
- watch をさせる
- es6, post-css を利用する
としています。サンプルとしてはこんなもんかと。
解説
フォルダ構成はこんな感じになる
.
├── .babelrc
├── bin
│ ├── css-build.sh
│ ├── css-minify.sh
│ ├── css-watch.sh
│ ├── develop.sh
│ ├── js-build.sh
│ ├── js-uglify.sh
│ ├── js-watch.sh
│ ├── production.sh
│ └── watch.sh
├── node_modules
├── .postcss.json
├── .postcss.production.json
├── package.json
├── public
│ ├── javascripts
│ └── stylesheets
└── src
├── javascripts
│ ├── a.js
│ ├── b.js
│ └── libs
└── stylesheets
├── a.css
├── b.css
└── libs
./src
のファイル群を ./public
に吐き出したい。
それぞれ a, b と2種類ずつエントリがあるとします。
複数のエントリを処理するときにしたこと。
js
の処理を考えた時に
愚直に一つ一つ書く方法をまず考えます。
"js:build:a": "browserify ./src/javascripts/a.js > ./public/javascripts/a.js",
"js:build:b": "browserify ./src/javascripts/b.js > ./public/javascripts/b.js"
ただ、こんな書き方をしていると辛くなります。
ということで、シェルスクリプト
を利用して処理を引数から動的に変更できるようにしましょう。
次のようにします。
"js:bin:build": "./bin/js-build.sh $filename"
#!/bin/bash
browserify ./src/javascripts/$1 > ./public/javascripts/$1
と準備して、次のように実行します
npm run js:bin:build -- a.js
npm run js:bin:build -- b.js
こうすることで、a.js
とb.js
を一つのタスクで処理することが可能になります。
npm script
は引数を渡すことができます。
npm run script -- hoge
と渡す決まりになっていて
この時に
command hoge
という風に実行されます。つまり シェルスクリプト
とは違って純粋に後ろに文字列が引っ付いて実行される形になります。
というわけで、引数をコマンド上に展開したい場合は一旦 npm script
を経由しても良いです。
ちなみに タスクの方では $filename
という引数を追加していますが、これには何も代入されず空文字列として処理されます。
ただ、シェルスクリプト
の中身は package.json
からは伺えないので、
このタスクは引数を取るよ ってことを伝えるには便利かなと思って入れてます。
css の minify について
今回は、.postcss.production.json
という、minify の処理を追加しただけの post-css
ようのファイルを用意した。
正直微妙な気もする。
諸注意
あとは、よくあるズッコケ
-
シェルスクリプト
の 実行権限 - 出力先のディレクトリがあるかどうか、ないとエラーが出たりする
感想
設計の仕方は人それぞれだと思います。
正直、watch
, build
, production
の シェルスクリプト
を1個ずつ用意したほうがコストは安いかも。。。と思ったりしました。
ただそれよりかは、シェルスクリプトをそれぞれに機能にバラして、どんなタスクがあるかを package.json
から見れたほうがいいかなーとか思ってこのサンプルを作りました。
ここら辺のベストプラクティスを共有したいなぁと思いますね。
俺はこうやっているよ。という方がいれば是非教えて欲しいですね。
あまりとりとめのない話になってしまった。誰かの参考になれば何より。