Apache+CakePHP3+Gulp環境設定 for Mac


CakePHPに最低限のバックエンド処理だけ持たせて，ルーティングなどはフロントエンドに丸投げするサイトを構成するための環境構築をしたので再構築時のためにメモ．

##Nodeの環境設定

Gulpを利用するため，Node.jsをMacに導入するがbrewを利用すれば一瞬で終わる．

```
brew install nvm
echo 'export NVM_DIR="$HOME/.nvm"' >> .bash_profile
echo '. "/usr/local/opt/nvm/nvm.sh"' >> .bash_profile
```

これでnvmコマンドが通るはずなのでお好みのNode.jsをインストールすればOK.

##CakePHPの環境設定

次にCakePHPの環境設定をするが今回はPHP7.1を利用している．またCakePHPのインストールにはPHPのパッケージマネジャーであるComposerを利用する．基本的に全部brewに任せるが，PHPのパッケージが存在するレジストリを登録する必要がある．

```
brew tap homebrew/homebrew-php
brew install php71 php71-intl
```

後ろのintlがついてるパッケージはComposerを利用するときに必要となるので，忘れずインストールする．続いてComponserをインストールして終了．

```
brew install composer
```

上手くいっていればcomposerコマンドがターミナル上で実行可能となる．これを利用してCakePHPのインストールを行う．自分が決めたワーキングディレクトリ上で以下のコマンドを利用することで完了．

```
composer create-project --prefer-dist cakephp/app cake
```

コマンド打ってから結構時間かかるので気長に待つ．エラーが出なければCakePHPプロジェクトの展開は完了．

##Apacheの環境設定

brewを利用するためPHPの時と同様にレジストリを新しく登録する必要がある．次のコマンドを実行すればインストール完了．

```
brew tap homebrew/apache
brew install httpd24
```

これでMac上にApacheが乗るのでapachctlコマンドが使える．これを利用してApacheの再起動などが可能．

あと先ほどのインストールではPHPとApacheを連携させるモジュールがインストールされていない．そこで下記のコマンドを実行する．上手く連携させてhttpd.confの中身を書き換えてくれる．ApacheをPHPより先にインストールするなら上記したinstallコマンドにオプションを付与すれば一発でOK.

```
brew reinstall php71 --with-httpd24
```

Apacheを起動する前にはPHPとの紐付けのためにApacheの設定がいるので/usr/local/etc/apache2/2.4/httpd.confを以下のように再設定する．
尚，今回はDocumentRootもユーザディレクトリ上に変更している．もし，Apacheでパーミッションエラーが出るようならchmodの755で権限を変更する必要がある．

```httpd.conf
DocumentRoot "/Users/[userName]/cake"
<Directory "/Users/[userName]/cake">
	...
AllowOverride All
	...
</Directory>

	...

AddType application/x-httpd-php .php

	...
	
DirectoryIndex index.php index.html

	...

<FilesMatch .php$>
SetHandler application/x-httpd-php
</FilesMatch>
```

これでApacheをrestartすればCakePHPのデフォルト画面に http://localhost:8080/ からアクセスできるはずである．

##Gulpの環境構築

フロントエンドに大きな処理を持たせるためにNodeからReactなどのライブラリを利用する．Sassの導入やnpmによる各モジュールのインストールについては割愛する．そのためにタスクランナーで開発環境を整備するが今回はJavascriptではReact+Reduxを採用し，さらにBrowserifyでトランスパイルを行なっている．CssにはSassを利用しており，同様にSassのコンパイルもGulpのタスクの１つに含める．その他，諸々を含めたコンパイル処理でのタスクフローは以下のようになる．

```Javascript:gulpfile.js
const gulp = require("gulp");
const rename = require("gulp-rename");
const browserify = require("browserify");
const babelify = require("babelify");
const source = require("vinyl-source-stream");
const buffer = require("vinyl-buffer");
const uglify = require("gulp-uglify");
const sourcemaps = require("gulp-sourcemaps");
const sass = require("gulp-sass");
const clean = require("gulp-clean-css");

gulp.task("js-compile", function() {
    var bundler = browserify({
        entries: ["./js/root.js"]
    }).transform(babelify, { presets: ["es2015", "react"] });
    return bundler.bundle()
           .pipe(source("bundle.js"))
           .pipe(gulp.dest("./webroot/js/"))
           .pipe(buffer())
           .pipe(sourcemaps.init())
           .pipe(uglify())
           .pipe(sourcemaps.write("./maps/"))
           .pipe(rename({extname: ".min.js"}))
           .pipe(gulp.dest("./webroot/js/"));
});

gulp.task("sass-compile", function() {
    return gulp.src("./sass/style.scss")
           .pipe(sass({ outputStyle: "expanded" }))
           .pipe(gulp.dest("./webroot/css/"))
           .pipe(clean())
           .pipe(rename({extname: ".min.css"}))
           .pipe(gulp.dest("./webroot/css/"))
});

```

今回CakeのデフォルトサーバでなくApacheを利用した最大の目的としてはbrowser-syncのproxy機能を利用した上で，CakePHP+Javascript環境でのライブリロードの実現としているので上記のプログラムに加えて以下のようにタスクを構成する．

```Javascript:gulpfile.js
const gulp = require("gulp");
const browser = require("browser-sync");

gulp.task("server", ["js-compile", "sass-compile"], function() {
    browser({
        proxy: "localhost:8080"
    });
    gulp.watch("./webroot/*.html", ["reload"]);
    gulp.watch("./webroot/*.php", ["reload"]);
    gulp.watch("./webroot/js/*.js", ["reload"]);
    gulp.watch("./webroot/css/*.css", ["reload"]);
});

gulp.task("reload", function() {
    browser.reload();
});

gulp.task("watch", function() {
    gulp.watch("./js/*.js", ["js-compile"]);
    gulp.watch("./js/**/*.js", ["js-compile"]);
    gulp.watch("./js/components/**/*.jsx", ["js-compile"]);
    gulp.watch("./sass/*.scss", ["sass-compile"]);
});

gulp.task("default", ["server", "watch"]);
```

PHPの監視機能が若干抜けているが．これに多少追記すれば開発環境の構築は終了である．gulpコマンドを叩けばプロキシサーバでのライブリロードが可能となる．