【個人開発】還暦プログラマ謹製「情報処理技術者試験ドットコム」のフロントエンド

# はじめに
はじめまして、5月に還暦を迎え、定年退職したプログラマ@toshio_fukeharaと申します。

転職後の講師業務のために「[情報処理技術者試験ドットコム](https://ipa-siken.com "ipa-siken.com")」というサービスを立ち上げました。

https://qiita.com/toshio_fukehara/items/85dee36029f741ded024

今回は、現職の[九州国際情報ビジネス専門学校](https://cosmet.ac.jp/ "九州国際情報ビジネス専門学校")の生徒に教えるつもりで、フロントエンドの技術面の話をしたいと思います。

# フロントエンドの選定
- SSR[^1]にするかCSR[^2]にするか
  - React を使って CSR にする手もあるが、セキュリティ面と SEO 対策で SSR にする。フレームワークはなじみの Laravel にするので Blade を利用する
    - CSR はセキュリティの問題を抱える可能性がある
    - CSR は改善が進んでいるが、クローラーがコンテンツを認識できない可能性がある 
  - 今後追加で開発するメンテナンスの機能は、CSR で React を利用する
    - 教室の管理者または内部で使うのみなので、SEO を考慮する必要なし 
[^1]: サーバーサイドレンダリング
[^2]: クライアントサイドレンダリング

# Grid.js
## 選定経緯
### 解答履歴、模擬試験履歴など表形式にしたい
- 並び替えできるようにしたい
- リロードせずに表示内容を更新したい
- 簡単にページングを実現したい
- セルの幅も変えられるようにしたい
 
### HTMLでゴリゴリ組むのはムリ。とりあえず grid javascript でググる
- Grid.js が先頭に出てきた
- 詳しく調べる。まずは[公式のサイト](https://gridjs.io/docs/examples/hello-world "gridjs.io") を見ないと
- わかりやすい！学習コストも低そう
- 並び替え機能あり
- 非同期で更新できる
- ページネーション機能あり
- セル幅も変更できる
- React でよく使っていた MUI X Data Grid なみの機能？
- github で 4.3k stars
- 直近のアップデートが 2024-03-03 で定期的に行われている

### 非同期での更新も簡単
  - Config にサーバーへの url 等を書いて、サーバー側の処理を準備すればOK 
```javascript:server.js
server: {
    url: "{{url('/data/chart/results')}}" + "?ipaType={{session('ipaType')}}",
    then: data => data.data.map(exam => [exam.correction, exam.category, exam.summary, exam.shortName, exam.review, exam.examCd, exam.seq]),
    handle: (res) => {
        if (res.ok) return res.json();
        throw Error('サーバーでエラーが発生しました。');
    },
},
```

## 利用シーン
![guide_history.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024019/62821ab3-5a0a-1893-3211-2c872f792983.png)

## 苦労した点
### ページネーションでの良くわからないエラー
- ローカルでは発生しないが、サーバーで以下のエラーが発生
- "An error happened while fetching the data"
  - stack overflow では pagination: true にする対応が載っていたが、それでもエラーとなる場合がある。pagination の行数は指定したいので、以下の対応を行った 
- Config で 'error': '情報処理技術者試験ドットコム', を設定して、メッセージを隠した。苦肉の策です

### 日本語化
- [公式 Grid.js ローカライズ](https://gridjs.io/docs/localization/locales "gridjs.io")
  - 公式にある Config の language に jaJP を指定する方法は CDN の gridjs.umd.js では l10n にある言語ファイルがないのでうまくいかず
    - TypeError: Cannot read properties of undefined (reading 'ja_JP')
  - github から gridjs のソースを取ってきて、jaJP の定義を確認して、自プロジェクト内に定義して、language: GRID_JS_LANGUAGE_JP と指定するようにしました 
```javascript:const.js
const GRID_JS_LANGUAGE_JP = {
    'search': {
        'placeholder': '検索...'
    },
    'sort': {
        'sortAsc': '昇順でソート',
        'sortDesc': '降順でソート',
    },
    'pagination': {
        'previous': '< 前',
        'next': '次 >',
        'navigate': (page, pages) => `${page} / ${pages} ページ`,
        'page': (page) => `${page} ページ`,
        'showing': '表示',
        'of': '件目（全',
        'to': '～',
        'results': () => '件）'
    },
    'loading': 'ロード中...',
    'noRecordsFound': 'データがありません。',
    'error': '情報処理技術者試験ドットコム',
}
```

# Chart.js
## 選定経緯
- javascript でチャートを出す定番
- 以前から利用していて機能不足はあまり感じてなかった
- わかりやすい！学習コストが低い

## 利用シーン
![guide_chart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024019/1681aa51-0891-ce52-03e3-838d1bcd6c70.png)

## 苦労した点
- グラフの更新
  - 非同期で更新する機能はGrid.jsのように標準ではない 
  - 再描画するには破棄(destroy)が必要

# Boostrap5
## 選定経緯
- 一から CSS 作成するのはムリ筋
- 以前から利用していて、わりと好きなデザインなので

## 利用シーン
- 全般にわたって使用しています
  - Bootstrap5 の Class を使ってデザインの統一性を持たせてます
![guide_answer_sel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024019/5f74476a-cf36-ea7f-f05e-ccc6c629296a.png)

# 終わりに
最後まで読んで頂いてありがとうございます！
無料でも結構使えます。情報処理技術者試験にトライされる際はぜひ使ってみてください。
副業で開発を請け負ってますので、ご依頼などありましたらご連絡ください。
[情報処理技術者試験ドットコム お問い合わせ](https://ipa-siken.com/contact "ipa-siken.com")