Gulp でビルドスクリプトを書く(PureScript で Hello, World!)
- 第1話 PureScript ver. 0.7.0 以上での Hello, World!
- 第2話 PureScript ver. 0.7.0 以上で “ブラウザーで” Hello, World!
- 第3話 NPM と Bower に依存を管理させる(PureScript で Hello, World!)
これらに続く第4話。前回では NPM の scripts
を使ってコマンドを書いてビルドをしていたんだが、sh と cmd と2つ管理しないといけなかったり、ワンライナーなんで保守がしづらかったりと問題があるので、今回はビルドツールである Gulp を使って PureScript のコードをビルドするようにする。
おさらい
前回使ったワンライナーはこんなんだった。
bower install && psc --ffi bower_components\purescript-*\src\**\*.js bower_components\purescript-*\src\**\*.purs src\Main.purs && psc-bundle output\*\*.js --module Main --main Main -o output\main.js && copy src\index.html output\
4つのステップがあるのでそれぞれ見ていく。
bower install
bower.json に記載した依存をインストールする。
psc --ffi bower_components\purescript-*\src\**\*.js bower_components\purescript-*\src\**\*.purs src\Main.purs
PureScript ソースコードをコンパイルして JavaScript に。
psc-bundle output\*\*.js --module Main --main Main -o output\main.js
CommonJS 仕様の JS コードをブラウザーで実行できるように変換する。
copy src\index.html output\
JS を読み込む HTML を成果物フォルダーにコピーする。
bower install
は初回にこれをそのまま実行してもらうとして、それ以外を Gulp スクリプトに変換していく。
gulpfile.js
Gulp スクリプトは単なる JS のコードで require('gulp')
すると使える内部 DSL である。今のワンライナーでは psc
コマンドで生成される途中成果物と psc-bundle
した後の最終成果物が同じフォルダー下にあって管理の問題上分けたいので、最終成果物は dest フォルダー下に置かれるようにする。そうすると、所望の Gulp スクリプトは下記のようになる。これを gulpfile.js として保存する。
'use strict'; var gulp = require('gulp'); var purescript = require('gulp-purescript'); var sources = [ 'src/**/*.purs', 'bower_components/purescript-*/src/**/*.purs', ]; var foreigns = [ 'src/**/*.js', 'bower_components/purescript-*/src/**/*.js' ]; var destination = 'dest'; gulp.task('make', function () { return purescript.psc({ src: sources, ffi: foreigns }); }); gulp.task('bundle', ['make'], function () { return purescript.pscBundle({ src: 'output/**/*.js', output: destination + '/main.js', module: 'Main', main: 'Main' }); }); gulp.task('copy', function () { return gulp.src(['src/**/*.html']) .pipe(gulp.dest(destination)); }); gulp.task('default', ['bundle', 'copy']);
雰囲気でだいたい分かると思うが簡単に説明すると、require('gulp-purescript')
で Gupl スクリプト内で PureScript 固有の記述ができるようになる。gulp.task
関数は第1引数にタスク名、第2引数に依存するタスクの配列、第3引数にタスクの内容のクロージャーを渡すようになっている。第2・第3引数は省略することができる。
このようにタスクを記述すると下記のようにタスクを実行することができるようになる。
> gulp make
引数なしで gulp
とだけ実行すると default
タスクが実行される。
依存の追加
新たに、Gulp を使用するようになったので package.json の devDependencies
に gulp
と gulp-purescript
を追加する。
"devDependencies": { "purescript": "0.7.2", "bower": "^1.4.1", "gulp": "^3.9.0", "gulp-purescript": "^0.7.0" }
NPM でインストールした Bower と Gulp を呼べるように package.json の scripts
を下記のようにする。当然既存のワンライナーのビルドコマンドはもう要らない。
"scripts": { "bower": "bower", "gulp": "gulp" }
ビルド手順
以上をまとめるとビルド手順は下記となる。
> npm install > npm bower install > npm gulp
ビルドを少し速くする
今の copy タスクでは前回ビルドから変更点がなくてもコピーしてしまっているので、最終変更日時を確認して必要のあるときだけコピーするようにする。変更点は下記である。
package.json
"devDependencies": { … "gulp-newer": "^0.5.1" }
gulpfile.js
var newer = require('gulp-newer') … gulp.task('copy', function () { return gulp.src(['src/**/*.html']) .pipe(newer(destination)) .pipe(gulp.dest(destination)); });
実行するコマンドに変更はない。