Laravel 8 で Zurb Foundation が使いたい

# 目標 

- Laravel 8.x の環境で、Zurb Foundation を使いたい
- コンパイルは Laravel Mix で

# 開発環境

Windows + Docker

## ホスト
- OS: Windows 10
- CPU: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
- RAM: 32 GB

## コンテナ
- APP: php:74-apache を元にLaravelが動くようにしたもの
- DB: mysql:5.7.36
- phpMyAdmin: phpmyadmin:latest
- mailhog: mailhog:latest

# 構築手順

## 前提
Laravelは動くようになってる（welcomeが表示される状態である）ものとする

## 参考
基本的な流れは、[Using Foundation 6 with Laravel 5 | Something New Tutorial](http://somethingnewtutorial.blogspot.com/2017/07/using-foundation-6-with-laravel-5.html)
こっちも見たけど、上記が丁寧だった [Using Foundation Zurb 6.3.0 with Laravel 5.4 | laracast](https://laracasts.com/discuss/channels/tips/using-foundation-630-with-laravel-54)

## 1. foundation-sitesのインストール
```
#npm install foundation-sites --save-dev
#npm update
```
これで foundation-sites がインストールされ、必要なものも入る

## 2. SCSS 関連の調整
### ディレクトリ
そもそもbootstrapように構築してないので、resources/sass もないし、app.scss もない。
なので、ディレクトリとファイルは作る。

### _settings.scss
Foundationの設定ファイルが必要なので、`node_modules/foundation-sites/scss/settings` からコピーする。

```
#cp -p node_modules/foundation-sites/scss/settings/_settings.scss resources/sass/_settings.scss
```

settings.scssの中に `@import 'util/util';` という記述があるので、パスを合わせるために以下のように変更する。

```
- @import 'util/util';
+ @import "../../node_modules/foundation-sites/scss/util/util";
```

### app.scss

このファイルも bootstrap がインストールされてればあるので、それを編集する
無いので作る
そして、bootstrap用の _variables.scss があるなら削除

```
// Settings
@import "settings";

// Foundation
@import "node_modules/foundation-sites/scss/foundation";

// Include Everything (True) for the Flex Grid :);
@include foundation-everything(true);
```

`@include foundation-everything(true);` はお好みで。flexbox mode を有効にするためのもの。
参考）[Flexbox Mode](https://get.foundation/sites/docs/flexbox-mode.html#enabling-flexbox-mode)

## 3. JS 関連の調整

### foundation.js
このファイルはbootstrap.jsからのコピーで作成できるのだが、bootstrapを使う環境でないと try-catch 部分が無いので、別環境で試した時のデータをコピペする

```
window._ = require('lodash');

/**
 * We'll load jQuery and the Bootstrap jQuery plugin which provides support
 * for JavaScript based Bootstrap features such as modals and tabs. This
 * code may be modified to fit the specific needs of your application.
 */

try {
    window.Popper = require('popper.js').default;
    window.$ = window.jQuery = require('jquery');

    require('bootstrap');
} catch (e) {}

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

/**
 * Echo exposes an expressive API for subscribing to channels and listening
 * for events that are broadcast by Laravel. Echo and event broadcasting
 * allows your team to easily build robust real-time web applications.
 */

// import Echo from 'laravel-echo';

// window.Pusher = require('pusher-js');

// window.Echo = new Echo({
//     broadcaster: 'pusher',
//     key: process.env.MIX_PUSHER_APP_KEY,
//     cluster: process.env.MIX_PUSHER_APP_CLUSTER,
//     forceTLS: true
// });

```

↑の try の中身変更と最後に追加

```
window._ = require('lodash');

/**
 * We'll load jQuery and Foundation Sites
 */
try {
    window.$ = window.jQuery = require('jquery');

    require('foundation-sites');
} catch (e) {}

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

/**
 * Echo exposes an expressive API for subscribing to channels and listening
 * for events that are broadcast by Laravel. Echo and event broadcasting
 * allows your team to easily build robust real-time web applications.
 */

// import Echo from 'laravel-echo';

// window.Pusher = require('pusher-js');

// window.Echo = new Echo({
//     broadcaster: 'pusher',
//     key: process.env.MIX_PUSHER_APP_KEY,
//     cluster: process.env.MIX_PUSHER_APP_CLUSTER,
//     forceTLS: true
// });

/**
 * initialize foundation 
 */

$(document).foundation();

```

### app.js

bootstrap から foundation に変更するだけ

```
- require('./bootstrap');
+ require('./foundation');
```

## 4. Mixの調整

以下が初期状態

```
mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]);
```

最初はsassは入ってない状態なので、JS＋SASS＋ソースマップ出力の状態に変更する

```
mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .sourceMaps();
```


## 5. テスト用ページ

welcome.blade.phpにfoundationのクラスを追加して動作確認する

### welcome.blade.php

ヘッダにcssの読み込みを追加

```
<link rel="stylesheet" href="css/app.css" type="text/css">
```

ボディタグ終端の直前にJSの読み込みを追加

```
<script src="js/app.js"></script>
```

Foundationが動いてるか確認のために本文に以下を追加

```
<div class="callout warning"><p class="lead">hogehoge</p><a href="https://laravel.com/" class="button success" target="_blank">Laravel</a></div>
```

## 6. テスト

コンパイル実行

```
# npm run dev

> dev
> npm run development

> development
> mix
        Additional dependencies must be installed. This will only take a moment.
        Running: npm install sass-loader@^12.1.0 sass resolve-url-loader@^4.0.0 --save-dev --legacy-peer-deps
        Finished. Please run Mix again.```
```

初回実行時には、「足りないものがあったので入れました。もう一回実行してね。」と言われるので、再度実行する

```
#npm run dev

● Mix █████████████████████████ done (99%) plugins
 WebpackBar:done

✔ Mix
  Compiled successfully in 29.02s
```
めっちゃ時間かかるやん。。。

これで、APPコンテナにアクセスして確認したら、完了

# 成果

とりあえず、出来た。
これに vue.js を追加しても良いな。と思っている

Laravel使うなら、Foundation使わずにBreezeとか、Jetstreamとかあるだろっていう人居るだろうけど、、、ｗ
少なくとも、BootstrapよりはFoundationが好きなのである。


とりあえず、今後のために残しておく。
ひょっとしたら、加筆・修正もするかも知れない。
時間を見つけて、Dockerfileとdocker-compose.ymlだけで上記が完結するようにもしておこうと思う。