NPM と Bower に依存を管理させる(PureScript で Hello, World!)

前々回の記事「PureScript ver. 0.7.0 以上での Hello, World!」、前回の記事「PureScript ver. 0.7.0 以上で “ブラウザーで” Hello, World!」に次ぐ記事。

NPM の package.json とか Bower の bower.json とかに依存を書いてビルドを簡単にするのが今回の目的。

おさらいと前提

ファイル一覧。

> dir /b
src
> dir /b src
index.html
Main.purs

ファイルの中身。src\index.html は下記。

<html><head><script type="text/javascript" src="main.js" ></script>

src\Main.purs は下記。

module Main where

import Control.Monad.Eff.Console (log)

main = log "Hello, World!"

NPM と Bower と依存するパッケージはすでにインストールしてある前提。

package.json

NPM の設定ファイルは package.jsonnpm init コマンドでいくつか質問に答えれば下記のような package.json ができるはず。

{
  "name": "purescript-hello-console",
  "version": "1.0.0",
  "main": "index.html",
  "dependencies": {},
  "devDependencies": {
    "bower": "^1.4.1",
    "purescript": "^0.7.0"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+ssh://git@github.com/kakkun61/purescript-playground.git"
  },
  "author": "Kazuki Okamoto",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/kakkun61/purescript-playground/issues"
  },
  "homepage": "https://github.com/kakkun61/purescript-playground",
  "description": ""
}

dependencies のバージョン番号のところの ^ はセマンティックバージョンを考慮して互換性のあるバージョンを表す NPM の文法らしい。

bower.json

Bower の設定ファイルは bower.json。NPM と同じように bower init コマンドで質問に答えていけば下記のような bower.json ができるはず。

{
  "name": "purescript-hello-console",
  "version": "1.0.0",
  "main": "index.html",
  "authors": [
    "Kazuki Okamoto"
  ],
  "license": "MIT",
  "homepage": "https://github.com/kakkun61/purescript-playground",
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ],
  "dependencies": {
    "purescript-console": "~0.1.0"
  }
}

~^ みたいなものっぽいけどいまいち分かってないので「node.js - What is the bower version syntax? - Stack Overflow」読んどいて。(丸投げ

ここまでで npm installbower install で依存をインストールすることはできるようにはなるけどビルドは手打ちなんでスクリプトにしておく。

NPM のスクリプト機能

package.jsonscripts の項目に下記を追記する。

    "build": "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 && cp src/index.html output/",
    "build-cmd": "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\\",

ユーザーが NPM で Bower をインストールしたことを考えると bower コマンドにパスが通ってない可能性があるので $(npm bin)/bower ってしておくべきなんだけど、package.json の中に書く場合は npm bin がパスに追加されている。($(npm bin)/bower だけ cmd じゃない…… cmd で同じことしようとすると for /f "usebackq" %p in (`npm bin`) do %p\bower とかになるはず。)

ここまで準備するとユーザーは NPM をインストールした後、下記コマンドでビルドしできた output\index.html をブラウザーで開けばよい。

> npm install
> npm run build-cmd

編集

2015.10.18

package.jsondependencies に記述していた bowerpurescriptdevDependencies に移した。これらは成果物が依存しているわけではなく開発時にのみ依存するため。