FullCalendar 4をlaravel/mixでビルドして利用する


LaravelのプロジェクトでFullCalendarを導入する方法についてまとめてみました。

FullCalendarを利用するにはscriptタグでソースを読み込む方法もありますが、メンテナンス性を考えるとパッケージをnpmで管理して、Laravel Mixを利用してビルドするのが良い方法です。

特にFullCalendar 4からはコア以外の機能はプラグインの形で都度追加する必要があるためよりパッケージ管理システムを利用することが推奨されています。

Laravel Mixとは

以前の記事、Laravel 6.x laravel/uiを利用してbootstrap 4を適用する で少し触れていますが、Laravel Mixは、Laravelのフロントエンド ビルド環境で、Webpackを簡単に利用するラッパーみたいなものです。

Laravel Mixのセットアップは以下のようにプロジェクトの作成後npm installするだけで、自らWebpack環境を用意しなくてもLaravelと組み合わせてVue.jsやReactを簡単に使い始められます。

$ composer create-project --prefer-dist laravel/laravel laravel-fullcalendar
$ cd laravel-fullcalendar
$ npm install

ビルドの設定はwebpack.mix.jsファイルに記述します。例えば、jsとcssのビルドする場合、以下のように入力ファイルと出力するディレクトリを指定するだけです。

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

とても簡単ですね。

ビルドはnpm run dev、開発中はnpm run watchしてすぐ開発が進められます。

また、通常Webpackで複数の入力ファイルを扱うのは工夫が必要ですが、Laravel Mixなら以下のように簡単に追加できます。

mix.js('resources/js/blog.js', 'public/js')
    .sass('resources/sass/blog.scss', 'public/css');
mix.js('resources/js/admin.js', 'public/js')
    .sass('resources/sass/admin.scss', 'public/css');

例えば、これはブログ記事と管理画面のビューで使うjsやcssのアセットをビルドするイメージです。

FullCalendarのインストール

ここから本題ですが、まずFullCalendarのパッケージをnpmで追加していきます。

この記事では、FullCalendarのビューはTimeGrid Viewのみを使用します。
また、予定をドラッグで変更できるようにするのと、複数のタイムゾーンに対応したいので、interactionmoment-timezoneも追加します。
まとめるとコアも含めFullCalendar関連は以下の4つのパッケージをインストールします。

  • @fullcalendar/core
  • @fullcalendar/timegrid
  • @fullcalendar/interaction
  • @fullcalendar/moment-timezone

また、@fullcalendar/moment-timezoneは、moment-timezoneを別途インストールする必要があります。

以下のコマンドでインストールします。

$ npm install @fullcalendar/core @fullcalendar/timegrid @fullcalendar/interaction moment-timezone @fullcalendar/moment-timezone

FullCalendarの実装

resources/js/app.jsを編集しても良いですが、FullCalendarはすべてのページで使用することは無いと思うので、js、cssファイルを分けます。

resources/js/fullcalendar.jsを追加して以下を記述します

// resources/js/fullcalendar.js
import { Calendar } from '@fullcalendar/core'
import timeGridPlugin from '@fullcalendar/timegrid';
import interactionPlugin from '@fullcalendar/interaction';
import momentTimezonePlugin from '@fullcalendar/moment-timezone';

document.addEventListener('DOMContentLoaded', function () {
  const calendarEl = document.getElementById('calendar');

  const calendar = new Calendar(calendarEl, {
    allDaySlot: false,
    plugins: [timeGridPlugin, momentTimezonePlugin, interactionPlugin],
    timeZone: 'Asia/Tokyo', // momentTimezonePlugin
    defaultView: 'timeGridWeek',

    events: []
  });

  calendar.render();
});

次に、スタイルシートresources/css/fullcalendar.scssを追加して以下を記述します。

// resources/css/fullcalendar.scss
@import "~@fullcalendar/core/main.css";
@import "~@fullcalendar/timegrid/main.css";

Laravel Mixの設定ファイルに上記のファイルを読み込む設定を追加します。

// webpack.mix.js

mix.js('resources/js/fullcalendar.js', 'public/js')
  .sass('resources/sass/fullcalendar.scss', 'public/css');

ここでビルドしてみましょう。

$ npm run dev

以下のように、ビルドされたresources/js/fullcalendar.jspublic/js/fullcalendar.jsに、resources/css/fullcalendar.scsspublic/css/fullcalendar.cssに出力されます。

Laravel Mixでjs、cssをビルド

生成したアセットをビューで読み込んで表示してみます。

とりあえずここではwelcome.blade.phpを以下のように置き換えてみます。

// resources/views/welcome.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <link href="{{ asset('css/fullcalendar.css') }}" rel="stylesheet">
        <script src="{{ asset('js/fullcalendar.js') }}" defer></script>
    </head>
    <body>
        <div id="calendar"></div>
    </body>
</html>

開発サーバーを起動してhttp://127.0.0.1:8000を開きます。

$ php artisan serve

予定を表示したり追加したりできませんが、FullCalendarの表示ができました。

FullCalendarをLaravelのビューに表示

, ,