【Rails初学者】Rails8にカレンダーを入れる　FullCalendar導入備忘録（Importmap編）

# Rails8にカレンダーを入れる。FullCalendar導入備忘録（Importmap編）


こんにちは。
Rails初学者の私がRails8、Importmap環境でFullCalendarを導入しようとしたときに、いろいろ苦戦した記録です。
忘れないために、記録として残します。


## 環境

- Rails8
- Importmap（Webpacker / jsbundling-rails は使用しない）
- Stimulus
- Bootstrap
- SCSS で CSS 管理（`app/assets/stylesheets/application.scss`）

---

## Stimulus を導入（未導入の場合）

```bash
bin/rails stimulus:install
```

## 1.FullCalendarのJSを保存
CDNからJSをダウンロードし、vendor/javascript/ に保存する
```bash
mkdir -p vendor/javascript
curl -o vendor/javascript/fullcalendar.js https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.js
 ```

## 2.`export default`を追記
上記で保存した`vendor/javascript/fullcalendar.js`の末尾に以下を追記
(保存ファイルを見たら色々と長いコードが書いてあり、びっくりしました。これをしないと、`Stimulus`からモジュールとして読み込めないのです。)
```bash
export default FullCalendar;
```

## 3.`config/importmap.rb`にpinを追加
``` ruby
# config/importmap.rb
pin "fullcalendar", to: "fullcalendar.js"
```

## 4.Stimulusコントローラを作成
```bash
bin/rails generate stimulus calendar
```
生成された`app/javascript/controllers/calendar_controller.js`に以下を記述
```javascript
import { Controller } from "@hotwired/stimulus"
import FullCalendar from "fullcalendar"

export default class extends Controller {
  connect() {
    const calendar = new FullCalendar.Calendar(this.element, {
      initialView: 'dayGridMonth',
      headerToolbar: {
        left: 'prev,next today',
        center: 'title',
        right: 'dayGridMonth,timeGridWeek,listWeek'
      }
    })
    calendar.render()
  }
}
```

## 5.HTML側にカレンダー要素を用意
任意のビューに以下を記述（例：app/views/calendars/index.html.erb）
```html
<!-- app/views/calendars/index.html.erb -->
<div data-controller="calendar" class="calendar-wrapper"></div>
```

## 6.CSS（main.min.css）を保存して読み込む
① CSSを保存
 ```bash
mkdir -p app/assets/stylesheets/fullcalendar
curl -o app/assets/stylesheets/fullcalendar/main.min.css https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.css
```
②`application.scss`に以下を追加
```scss
@import "fullcalendar/main.min";
```
③自分が作成したいデザインのscssを追加
```scss
// app/assets/stylesheets/components/_calendar.scss

.calendar-wrapper {
  max-width: 720px;
  margin: 2rem auto;
  padding: 1.5rem;
  background: #fff0f5;
  border: 1px solid #f8c4d6;
  border-radius: 16px;
  box-shadow: 0 2px 8px rgba(248, 196, 214, 0.3);

  .fc {
    background-color: white;
    border-radius: 12px;
    overflow: hidden;
  }

  .fc-toolbar-title {
    color: #d36d8f;
    font-size: 1.4rem;
    font-weight: bold;
  }

  .fc-button {
    background-color: #f8c4d6;
    border: none;
    color: #7a2e46;
    border-radius: 8px;
    padding: 0.4rem 0.8rem;

    &:hover {
      background-color: #f4a4bd;
    }
  }

  .fc-daygrid-day-number {
    color: #d36d8f;
    font-weight: bold;
  }

  .fc-day-today {
    background-color: #ffe3ec !important;
  }
}
```
```scss
// application.scss にインポートを追加
@import "components/calendar";
```
### 表示確認をする
```
bin/dev
```

### まとめ
| 項目        | 内容                                        |
| --------- | ----------------------------------------- |
| JS保存      | CDN から JS をダウンロードして vendor/javascript に配置 |
| export追記  | `export default FullCalendar;` を手動で追加     |
| importmap | `pin "fullcalendar"` を `importmap.rb` に追加 |
| Stimulus  | `this.element` でカレンダーを描画                  |
| HTML構造    | `data-controller="calendar"` を指定          |
| CSS対応     | CSS は JS 経由ではなく SCSS に `@import`          |
| スタイル調整    | `.calendar-wrapper` にスタイル適用       |


### 自分用メモ
- `Webpack`を使わずにカレンダーを表示してみたかったが、`Importmap + Stimulus`を使用することが初めてだったため、たどり着くまでに苦戦した。
- 特に `main.min.js` に `main.css` が埋め込まれていて、それが原因で MIMEtypeエラーの対応にだいぶ時間をかけた  
- 手作業でJSを保存 → `export default` を追記 → CSSを別で読み込む、という流れにしてみるのが良さそう
- 細かいデザインは後で修正するとして、まずはFullCalendarを表示するところまでできた


---------
初学者のため、間違えていたらすいません。