デザイナー, フロントエンドエンジニアとの共同作業の悩みをLaravel Mixで解決する

この記事は [Laravel Advent Calender 2017](https://qiita.com/advent-calendar/2017/laravel) 8日目の記事です🎁

![](https://i.gyazo.com/e447d8ee465d1f4850ba422bf1e3d11c.gif)


Webアプリケーションをデザイナーさん/コーダーさんと共同開発することってあると思うんですけどその時にわりとエンジニアは、こういうものだからテンプレートの書き方これなんで覚えてください、開発環境作ったのでこれの上でやってください、という事を言いがち。それでもデザイナーさん達はキャッチアップして開発に参加してくれるので本当に頭が上がらない存在。だけどその悩みを少しでも解決出来たらいいなと思っててLaravelで前回の案件をやっていて共同でやっていた方と閃いた構成が良かったので共有してみます。

## デザイナーさんと共同で作業する時の共通な悩み

### フレームワークごとの書き方に振り回される問題
Railsだったらslimやhamlのシンタックス、そしてRailsのヘルパー群の使い方を学ぶ必要がある。Laravelだったらblade、Laravelのヘルパーを。HTMLの知識とは別のサーバーサイド都合の知識を要求されがち。

デザイナーさん的にはHTML, CSS, Javascript (+α)だけでデザイン出来る環境の方が仕事しやすいのでは？

### 開発環境整えるのめんどくさい問題
DockerやVagrantが整ってきているので開発環境構築の自動化はある程度どのプロジェクトでも当たり前に提供されつつありコマンド一つで開発環境構築が完了できるようになってきてる。だけどデザイナーさんにとってLinuxやDBやサーバーサイドの知識って求めていいものなのかあやしい。ひとたび動かなくなるとエンジニアの人に頼む必要があって、それに答えるのをこちらとしてはなんともないけど、デザイナーさん的には助けてもらうのを何度もお願いするのって大変だったりしないのか気になる。またデータベースのデータを用意したり、変更があった場合にmigrationしたり。

デザイナーさん的にサーバーサイドの事は一切気にせずにMac上だけでデザイン出来たほうが効率いいんじゃないだろうか？

### レビューコスト高い問題
デザイナーさんにアプリケーションのviewテンプレートを直接さわってもらうとして、それをGithubでPR投げてもらう、それが出来るすごいデザイナーさんは最近けっこう増えて来ててとてもありがたい事。なんだけど触ってもらうとなるとそれなりにちゃんとエンジニアがレビューする必要があり、レビューに複数回往復が必要になることが発生するのでお互いのコストが高い。またエンジニアが同じ箇所を修正したりとコンフリクトが起こりがち。gitのコンフリクトをさっと修正出来てしまうデザイナーさんを除いてその作業はめんどうな作業でできるだけ起きない方が望ましい。

デザイナーさん的にレビュー、gitの作業コストは最小限の方が良いのでは？

**それLaravel Mixで解決しちゃいましょう。**


## Laravel Mix とは

https://readouble.com/laravel/5.4/ja/mix.html


> Laravel Mixは多くの一般的なCSSとJavaScriptのプリプロセッサを使用し、Laravelアプリケーションために、構築過程をWebpackでスラスラと定義できるAPIを提供しています

Laravel 5.4 から提供されたCSSやJavascriptなどのassetsをいい感じに作成するために使用される機能です。webpackベースで動いていて、babelが標準で取り込まれているのでLaravelのプロジェクトを作ったそばからES2015の記述が利用できるように出来ています。またパッケージ管理はnpmを使用します。

Laravel Mixの特筆すべきところはLarvelという名を持ちながらも機能は全てNode.jsだけで作られている点です。そのため、[npm](https://www.npmjs.com), [webpack](https://webpack.github.io), [Gulp](https://gulpjs.com), [Babel](https://babeljs.io) など、Node.jsの資産をそのまま使う事が出来ます。 

Javascript, CSSの開発にPHPの環境を用意する必要もありません。またLaravelのプロジェクトのソースの中でなくても動作します。この点を利用して今回はデザイン用のディレクトリを作成してデザインをするためだけの閉じた環境を作成します。


## 構築編

前置き長くなりました。ここから技術的なこと入ります。(デザイナーさんで、難しいと思った方はエンジニアにこれ作って！ってお願いしてください :pray: )

app root配下では本番環境と同じOSでコンパイルした方が良いですが、新しく作るdesign環境ではMacのローカルで行います。これはLaravel MixがmacOSでの開発に最適化されいて通知を受けれる事と、`npm run watch` がmacOSで動くfseventsに依存していて仮想ホスト上のLinuxではwatchが使えずwatch-pollを使うことになるのですがCPUの処理がなぜか高負荷だったりする事があるのでMacのローカルを推奨します。デザイナーさんにも環境提供せずに済みますし。

`npm` を利用できる必要があるのでインストールが必要な人はしてください。


```bash
$ brew install node
```

designディレクトリを作成し、必要なファイルをコピーします

```bash
$ mkdir -p design/resources
$ cp webpack.mix.js design
$ cp package.json design
$ cp -R resources/assets design/resources/    
$ cd design
$ npm install && npm run dev
```

### ディレクトリ構造

resourcesとLarvel Mixに必要なファイルをdesignディレクトリ内にコピーし、そちらでデザイナーさんは作業を行う

```
- app
- resources
  - assets
    - js
      - app.js
    - sass
      - app.css
  - views
    - layouts
      - app.blade.php
    - books
      - index.blade.php
- design # resources や Laravel Mixに必要なファイルをコピーしたディレクトリ
  - resources
    - js
      - app.js
    - sass
      - app.css
  - views
    - layouts
      - app.ejs
    - books
      - index.ejs
  - gulpfile.js
  - package.json
  - package-lock.json
  - webpack.mix.js
  - public # design内でcompileされたassetsが入る
    - assets
      - js
        - app.js
      - css
        - app.css
    - views
      - books
        - index.html
- package.json
- package-lock.json
- webpack.mix.js
- public
  - assets # compiled assets by Laravel mix
    - js
      - app.js
    - css
      - app.css
```


![](https://d2mxuefqeaa7sj.cloudfront.net/s_EE0C026F4BF400171B637D9907D49F91FE020904129546B23E0B0F6948683C49_1512646906997_1_____Development_src_github_com_saboyutaka_mix-design_design__zsh_.png)


Javascript, CSSのassetsのコンパイルはこれだけで終わりです。

### Gulp, EJS, BrowserSync でデザイン開発環境を加速させる

#### [Gulp](https://gulpjs.com)

Gulpはタスク自動化ツールで開発時に便利な機能がたくさん提供されています。コンパイルはLaravel Mixで行っているのでこちらではEJSとbroserSyncを利用するために利用します。

#### [EJS](http://ejs.co)

EJSはJavascriptの軽量テンプレートエンジンです。HTMLファイルを利用してもいいのですが、共通部分(headerやfooter)をまとめておきたい、繰り返し要素をコピペするとメンテナンス性が低い、動的な値を入れるような書き方をしたい、などの要求をかなえるためにEJSを使用します。覚える事はそこまで多くない、はずです。。。

#### [Browsersync](https://www.browsersync.io)

ソースコードの変更を検知してブラウザを自動でリフレッシュする機能を提供します。

#### インストール

`npm install --dev gulp gulp-cached gulp-ejs gulp-notify gulp-plumber`

* [design/package.json](https://github.com/saboyutaka/mix-design/blob/master/design/package.json#L11)に`gulp`タスクを追加
* [design/gulpfile.js](https://github.com/saboyutaka/mix-design/blob/master/design/gulpfile.js) を追加

#### ejsファイルを配置
* [design/resources/views/index.ejs](https://github.com/saboyutaka/mix-design/blob/master/design/resources/views/index.ejs) ## 画面一覧
* [design/resources/views/layouts/_header.ejs](https://github.com/saboyutaka/mix-design/blob/master/design/resources/views/layouts/_header.ejs) ## 共通ヘッダー
* [design/resources/views/layouts/_footer.ejs](https://github.com/saboyutaka/mix-design/blob/master/design/resources/views/layouts/_header.ejs) ## 共通フッター

gulpの設定で_が先頭につくファイルはpublic配下に配置しないようにしています。

#### 各ページ
* [design/resources/views/books/index.ejs](https://github.com/saboyutaka/mix-design/blob/master/design/resources/views/books/index.ejs)
* design/resources/views/books/show.ejs
* design/resources/views/profile/show.ejs

### 実行

`npm run watch`, `npm run gulp` をそれぞれ実行します。

`npm run watch` はLaravel MixでJavascript, CSSのコンパイルを担当します。`dev`と同じですが、 `watch` コマンドは常駐しファイルの変更があるたびにコンパイルを実行します。

`npm run gulp` はgulpfile.jsをもとにタスクを実行します。今回の例ではEJSをコンパイルしHTMLを生成し`public/views`配下に配置します。またBrowserSyncでHTML, CSS, JSファイルが変更された際にブラウザを自動でリロードします。

これでHTML(EJS), Javascript, CSSだけに集中して開発できる環境が整いました。

![](https://i.gyazo.com/e447d8ee465d1f4850ba422bf1e3d11c.gif)

変更したCSS, Javascriptをアプリケーションに取り込む場合は、`design/resources/assets`をアプリケーション側にコピーします。

```
## エンジニアの開発環境(Dockerとか)で実行

$ cp -R design/resources/assets resources/
$ npm run dev
```

このコマンドもnpm scripts に入れてしまうと便利です。
`$ npm run de2re && npm run dev` 
※ de2re ･･･ design to resourceの略

## 運用編
開発のフロートしてGithubflowを採用していることを想定しています。

### デザイナーさん
作業は基本的にMac上のdesignディレクトリ

1. 作業ブランチをmasterブランチから作成する e.g. `git checkout -b sample_design`
2. designに移動し作業をデザイン環境で作業する。
3. 作業とコミットを繰り返す
4. 作業が一段落するとGithubにブランチをpushし、PullRequestを作成する。
5. PRは基本的に**レビューをスキップし、セルフマージ**する。エンジニアや他の人にチェックしてもらいたい場合はレビューしてもらう。

### エンジニアさん
作業はDocker, Vagrantで用意したLinux環境

1. `npm run de2re && npm run dev` で最新のassetsを取り込む
2. `design/resources/views`の変更をもとにアプリケーションのviewを手動で修正していく。(なんかもっといい方法あるかも)
3. デザイナーさんが作成したレイアウトやCSS, Javascriptなどに問題や提案がある場合はデザイナーさんと相談し、design ディレクトリを修正する。
4. PRを作成し、mergeする。

デザイナーさんがデザインを作成する途中はレビューを行わずに、エンジニアが手動で取り込むことで**作業中に実質のレビューが非同期に行われる事**が今回の作業フローの肝です。

以上の作業フローで、

* HTML, CSS, Javascriptだけを書ける環境を提供
* 開発環境はMacに`node`を入れるだけで完了
* レビューフローの簡略化

を行いました。

## 向いてる状況、向いてない状況
### 向いてる状況
エンジニアとデザイナーが共同で同時に開発してる時ほど効果がありそうです。レビューでエンジニアとデザイナーの手を双方で止める事なく、それぞれのタスクに集中する事が出来ます。

### 向いてない状況
ソースの管理が二重になってしまうので、ちゃんとメンテせずにアプリケーションのviewを直接触り始めるとdesignディレクトリが簡単に陳腐化します。なのでdesignディレクトリを面倒見るコストと、チームの手を止めないことのどちらが大きいかで採用するかどうかを決めると良さそうです。一人で作業してるときにはやる必要ないのかなとも思います。ただ、gulpとwatchで自動更新しながらデザインを構築していくのは結構快適なので、一人開発のときでも採用するのもありかもしれません。

またすでにアプリケーションの規模が大きく画面数が多い場合は環境構築するコストと得られるメリットの差がそんなに大きくない場合は採用するのが難しそうです。

## まとめ
とにかくLaravel Mix最高。Laravel自体の設計思想も良くて書き心地が良いのもありますが、フロントエンド周りの扱いがいい感じなだけでLaravel採用してもいいぐらいにはLaravel Mixが良いです。今回たまたまた思いついた構成でうまくデザイナーさんと作業がうまく行ったので他の人も試してもらって感想を聞けたらいいなと思います 🙌

サンプルアプリはgithubに公開しています。実際に触ってみると理解しやすいかもです。
https://github.com/saboyutaka/mix-design