Elixir
Phoenix

PhoenixフレームワークでBrunchもGulpもGruntも使いたくない場合

More than 3 years have passed since last update.

対象

BrunchもGulpもGruntも面倒くさいんじゃ〜!
npm run <something>コマンドでjsと付き合いたいんじゃ〜!!
というあなたに届けます。

ですが、BrunchからGulpやGruntに替える際も参考になると思います。

前提として、今回はmix phoenix.newの時に--no-brunchオプションは付けていません。

あ、大事なこと書き忘れてた。本編はElixir Phoenix + Browserifyをアレンジしたものです。

手順

nodeモジュールを全部消します。

$ rm -rf node_modules

package.jsonを編集してbrunch周りを全部消します:

packange.json
{
  "repository": {
  },
  "dependencies": {
  }
}

js周りのパッケージをインストールします:

$ npm install watchify browserify babelify uglify-js --save-dev
$ npm install babel-preset-es2015 babel-preset-react --save-dev

--saveじゃなくて--save-dev付けてますが、npmパッケージじゃないのでどっちでもいいです。babelの方はお好みで変えて下さい。

babelの設定ファイルを書きます:

.babelrc
{
  "presets": [
    "es2015",
    "react"
  ]
}

css周りのパッケージをインストールします:

$ npm install catw --save-dev

sass/less/stylus/postcssなどをお使いの方はそれ用のパッケージに書き換えてください。

assets周りのパッケージをインストールします:

$ npm install watch-run --save-dev

あとtest周りはお好みで入れて下さい。

package.jsonscripts部分を書きます:

package.json
{
  "repository": {},
  "scripts": {
    "build-assets": "cp -r web/static/assets/* priv/static",
    "watch-assets": "watch-run -p 'web/static/assets/*' npm run build-assets",
    "build-js": "browserify -t babelify web/static/js/app.js | uglifyjs -mc > priv/static/js/app.js",
    "watch-js": "watchify -t babelify web/static/js/app.js -o priv/static/js/app.js -dv",
    "build-css": "cat web/static/css/*.css > priv/static/css/app.css",
    "watch-css": "catw web/static/css/*.css -o priv/static/css/app.css -v",
    "build": "npm run build-assets && npm run build-js && npm run build-css",
    "watch": "npm run watch-assets & npm run watch-js & npm run watch-css",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {},
  "devDependencies": {
    "babelify": "^7.2.0",
    "browserify": "^12.0.1",
    "catw": "^1.0.1",
    "uglify-js": "^2.6.1",
    "watch-run": "^1.2.4",
    "watchify": "^3.6.1"
  }
}

これでnpm run watchで開発用、npm run buildでプロダクション用のjs/css/assetsがコンパイルできるようになりました。

web/static/js/app.jsでphoniex_htmlのjsファイルをアプリケーションルートを基準に読み込む設定になってるので、browserify/babelが分かるように書き換えます:

web/static/js/app.js
import "../../../deps/phoenix_html/web/static/js/phoenix_html"

最後にconfig/dev.exswatchersの部分を書き換えます。

config/dev.exs
config :goal_server, GoalServer.Endpoint,
  http: [port: 4000],
  debug_errors: true,
  code_reloader: true,
  cache_static_lookup: false,
  check_origin: false,
  watchers: [npm: ["run", "watch"]] # ←この行

これでmix phoenix.serverコマンドで自動的にnpm run watchを動かすようになりました。

プロダクションリリースの際にはサービス起動前にnpm run buildが走るように各種ツールの設定ファイルを書くのを忘れないようにしてください。

まとめ

Brunch外しのポイントは、web/static/js/app.jsconfig/dev.exsの書き換えですね。GulpやGruntに替える際もそこを注意すれば良いと思います。

最後にgit diffの結果を貼っておきます:

diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..bd20dc1
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,6 @@
+{
+  "presets": [
+    "es2015",
+    "react"
+  ]
+}
diff --git a/config/dev.exs b/config/dev.exs
index 8fbca2c..c622b18 100644
--- a/config/dev.exs
+++ b/config/dev.exs
@@ -12,7 +12,7 @@ config :goal_server, GoalServer.Endpoint,
   code_reloader: true,
   cache_static_lookup: false,
   check_origin: false,
-  watchers: [node: ["node_modules/brunch/bin/brunch", "watch", "--stdin"]]
+  watchers: [npm: ["run", "watch"]]

 # Watch static and templates for browser reloading.
 config :goal_server, GoalServer.Endpoint,
diff --git a/package.json b/package.json
index eb0a7bc..ad955bf 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,25 @@
 {
-  "repository": {
+  "repository": {},
+  "scripts": {
+    "build-assets": "cp -r web/static/assets/* priv/static",
+    "watch-assets": "watch-run -p 'web/static/assets/*' npm run build-assets",
+    "build-js": "browserify -t babelify web/static/js/app.js | uglifyjs -mc > priv/static/js/app.js",
+    "watch-js": "watchify -t babelify web/static/js/app.js -o priv/static/js/app.js -dv",
+    "build-css": "cat web/static/css/*.css > priv/static/css/app.css",
+    "watch-css": "catw web/static/css/*.css -o priv/static/css/app.css -v",
+    "build": "npm run build-assets && npm run build-js && npm run build-css",
+    "watch": "npm run watch-assets & npm run watch-js & npm run watch-css",
+    "test": "echo \"Error: no test specified\" && exit 1"
   },
-  "dependencies": {
-    "babel-brunch": "^6.0.0",
-    "brunch": "^2.0.0",
-    "clean-css-brunch": ">= 1.0 < 1.8",
-    "css-brunch": ">= 1.0 < 1.8",
-    "javascript-brunch": ">= 1.0 < 1.8",
-    "uglify-js-brunch": ">= 1.0 < 1.8"
+  "dependencies": {},
+  "devDependencies": {
+    "babel-preset-es2015": "^6.3.13",
+    "babel-preset-react": "^6.3.13",
+    "babelify": "^7.2.0",
+    "browserify": "^12.0.1",
+    "catw": "^1.0.1",
+    "uglify-js": "^2.6.1",
+    "watch-run": "^1.2.4",
+    "watchify": "^3.6.1"
   }
 }
diff --git a/web/static/js/app.js b/web/static/js/app.js
index 8f61e4d..55dd958 100644
--- a/web/static/js/app.js
+++ b/web/static/js/app.js
@@ -11,7 +11,7 @@
 //
 // If you no longer want to use a dependency, remember
 // to also remove its path from "config.paths.watched".
-import "deps/phoenix_html/web/static/js/phoenix_html"
+import "../../../deps/phoenix_html/web/static/js/phoenix_html"

 // Import local files
 //