【2022年版】Laravel8にBootstrap導入時の3つのポイント

zax_developerLaravel

こんにちは、ザックス株式会社の開発担当の竹内です。

今回は以下の3つのポイントに注意して、Laravel8にBootstrapを導入していきたいと思います。

(1)非推奨のLaravel UIは使わない
Laravel8でも使用できますが公式では非推奨になっていますので使わないようにします。

(2)jQueryを使えるようにする
Bootstrap5からはjQueryへの依存はありませんが、Bootstrapに関係なくjQueryを使う開発者も多いかと思いますので、使えるようにします。

(3)BootstrapとTailwind CSS両方を使えるようにする
BreezeやJetstreamのデザインをそのまま流用するケースを想定し、BootstrapとTailwind CSSの両方を使えるようにします。

目次

  1. 前提条件と動作環境
  2. npmで必要なパッケージをインストール
  3. BootstrapやjQuery等の読み込みを設定ファイルに追記
  4. laravel-mixでビルド・コンパイルする内容を修正
  5. npx mixでビルド・コンパイルする
  6. ビルトインサーバーを起動し、ブラウザからログイン画面等を確認
  7. 動作テスト
  8. 最後に

1.前提条件と動作環境

JetstreamまたはBreezeがインストールされていることを前提とします。
※今回はJetstreamが動作する環境で検証します

動作環境は以下のとおりです。

  • Oracle VM VirtualBox 6.1.32に仮想環境を構築
  • Rocky Linux:8.5(Green Obsidian)
  • PHP:7.4.27
  • Composer:2.2.6
  • MariaDB:15.1
  • Laravel Installer:4.2.10
  • npm:8.3.1
  • nodebrew:1.1.0
  • Node.js:16.14.0
  • Laravel Jetstream:2.6.8
  • Firefox:91.5.0wsr(64ビット)
※以下のディレクトリ構成で進めていきます。(sampleがアプリのルートディレクトリになります)
/home/ユーザー名/laravel/sample/

2.npmで必要なパッケージをインストール

アプリのルートディレクトリで作業していきます。
Bootstrap、popper.js、jQueryをnpmコマンドを使ってインストールする前に一度package.jsonを確認しておきましょう。

package.json
{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },
    "devDependencies": {
        "@tailwindcss/forms": "^0.4.0",
        "@tailwindcss/typography": "^0.5.0",
        "alpinejs": "^3.0.6",
        "axios": "^0.21",
        "laravel-mix": "^6.0.6",
        "lodash": "^4.17.19",
        "postcss": "^8.1.14",
        "postcss-import": "^14.0.1",
        "tailwindcss": "^3.0.0"
    }
}

それではインストールします。

$ npm i bootstrap
$ npm i @popperjs/core
$ npm i jquery

再度package.jsonを確認すると、bootstrap,@popperjs/core,jqueryが追加されています。

package.json
{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },
    "devDependencies": {
        "@tailwindcss/forms": "^0.4.0",
        "@tailwindcss/typography": "^0.5.0",
        "alpinejs": "^3.0.6",
        "axios": "^0.21",
        "laravel-mix": "^6.0.6",
        "lodash": "^4.17.19",
        "postcss": "^8.1.14",
        "postcss-import": "^14.0.1",
        "tailwindcss": "^3.0.0"
    },
    "dependencies": {
        "@popperjs/core": "^2.11.4",
        "bootstrap": "^5.1.3",
        "jquery": "^3.6.0"
    }
}

3.BootstrapやjQuery等の読み込みを設定ファイルに追記

Bootstrap、popper.js、jQueryを読み込むようにresources/js/bootstrap.jsに追記します。
try {} catch (e) {}の部分です。

resources/js/bootstrap.js

変更前
window._ = require('lodash');

/**
 * 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';
...

変更後
window._ = require('lodash');

try {
  window.$ = window.jQuery = require('jquery');
  window.Popper = require('@popperjs/core');
  window.bootstrap = 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';
...

次にresourcesディレクトリにsassディレクトリを作成し、app.scssを追加します。
bootstrapのSCSSファイルをインポートします。

resources/sass/app.scss
@import '~bootstrap/scss/bootstrap.scss';

4.laravel-mixでビルド・コンパイルする内容を修正

laravel-mixは、CSSやJSをビルド・コンパイルするツールになり、webpackのwrapper(ラッパー)と言われています。
それでは、さきほどのSCSSファイルを含めるようにwebpack.mix.jsに、.sass()の部分を追記します。
これによりpublic/css/app.cssとしてまとめて出力することができます。

.postCss([]);部分は削除しないように注意してください。

webpack.mix.js

変更前
...
mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        require('postcss-import'),
        require('tailwindcss'),
    ]);
...

変更後
...
mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .postCss('resources/css/app.css', 'public/css', [
        require('postcss-import'),
        require('tailwindcss'),
    ]);
...

5.npx mixでビルド・コンパイルする

npx mixコマンドでビルド・コンパイルします。

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

npx mixコマンドは、不足している必要なパッケージを自動で検出し、インストールしてくれます。
もう一度npx mixコマンドを実行します。

$ npx mix
...
webpack compiled successfully

無事にコンパイルが完了しました。

6.ビルトインサーバーを起動し、ブラウザからログイン画面等を確認

画面が崩れていないか確認します。
以下のコマンドでビルトインサーバーを起動します。

$ php artisan serve
Starting Laravel development server: http://127.0.0.1:8000
[Mon Mar 21 12:32:28 2022] PHP 7.4.27 Development Server (http://127.0.0.1:8000) started

ブラウザを起動してログイン画面、ユーザー登録画面、ログイン後のダッシュボードを確認します。

ログイン画面
ユーザー登録画面
ログイン後のダッシュボード

BootstrapとTailwind CSSを1つのファイルapp.cssとしてコンパイルしたものをViewで読み込み、画面のレイアウトが崩れていないことを確認できました。
確認が終わりましたらビルトインサーバーを停止しておきましょう。
停止コマンドは、Ctrl+C(Macの場合はcontrol+C)になります。

7.動作テスト

念のためBootstrap、jQuery、Tailwind CSSの動作テストを行います。viewにテストページを用意します。
まずview(test.blade.php)を作成します。

resources/views/test.blade.php

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Bootstrap&jQuery& popper.jsのテスト</title>
  {{-- CSS --}}
  <link rel="stylesheet" href="{{ asset('css/app.css') }}">
  {{-- JS --}}
  <script src="{{ asset('js/app.js') }}" defer></script>
  {{-- popper.js CSS --}}
  <style>
    #tooltip {
      background: #333;
      color: white;
      font-weight: bold;
      padding: 4px 8px;
      font-size: 10px;
      border-radius: 4px;
    }
  </style>
</head>
<body>
{{-- Bootstrapテスト --}}
<div class="alert alert-success" role="alert">
Bootstrapでデザイン
</div>
{{-- Tailwind CSSテスト --}}
<p class="text-xl text-red-500">テキストサイズおよび色をTailwind CSSで変更</p>
{{-- popper.jsテスト --}}
<button id="button" class="btn btn-primary" aria-describedby="tooltip">ボタン</button>
<div id="tooltip" role="tooltip">ツールチップ</div>

<script type="module">
  //jQueryテスト
  $(document).ready(function () {
    console.log('jQueryテスト');
    //Bootstrap JavaScriptテスト
    console.log(bootstrap.Tooltip.VERSION);
  });
  //popper.jsテスト
  const button = document.querySelector('#button');
  const tooltip = document.querySelector('#tooltip');

  Popper.createPopper(button, tooltip, {
    placement: 'right',
  });
</script>
</body>

次にルーティングを設定します。
さきほど追加したtest.blade.phpをブラウザから見れるようにします。

routes/web.php
...
Route::get('test', function () { return view('test'); });

ビルドインサーバーを起動し、ブラウザでhttp://127.0.0.1:8000/testにアクセスします。
BootstrapのCSS、JS部分やjQueryの動作、Tailwind CSSが問題ないことを確認します。
※ブラウザの開発者ツールのconsoleタブからjQueryの動作とBootstrapのJSが動作していることを確認できます。

補足ですが、先ほど作成したtest.blade.phpにあるbody閉じタグ前のscript開始タグにtype=moduleを設定しています。
body閉じタグ前のscript開始タグにtype=moduleを設定することで、インラインスクリプトであってもDOM構築後に読み込みます。
またheadタグで読み込んでいるapp.jsはdefer属性が付いているため、HTMLのパースが完了してから読み込みます。
整理すると「HTMLのパースが完了」→「app.jsを読み込み」→「body閉じタグ前のインラインスクリプトを実行」という順番になります。
type=moduleを設定していない場合、body閉じタグ前のscript(インラインスクリプト)が先に読み込まれるため、jQueryが見つからず動作しないので注意してください。

test.blade.php

8.最後に

今回は以下3つのポイントに注意してBootstrapをインストール・動作テストをするところまで解説しました。

(1)非推奨のLaravel UIは使わない
(2)jQueryを使えるようにする
(3)BootstrapとTailwind CSS両方を使えるようにする

最後までお読みいただきありがとうございました。