環境構築からサーバサイドレンダリングでbootstrap5を使うまで

## 背景

初めてサーバサイドレンダリングを使った．
忘れないうちに，環境構築からサーバでCSSを読み込むまでをメモしておこうと思う．
bootstrap5を使えるようにするまでに結構詰まったので役にたつ人がいればなと思う．
今回は，Node.jsとpugをベースにbootstrap5を使ってみる．

## 雰囲気理解のサーバレンダリング

![ssr概要.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3600683/eb459a8d-64bc-05cf-90d5-c1dd31306e10.png)

サーバサイドレンダリングは，アプリケーションサーバでページ(HTML)を生成して提供する方式．
サーバでページを生成することで，スマホなどの低めの性能を持つ端末でも，比較的早い速度でブラウザでの表示が可能となる．
(最近はそこまで低い性能端末がないのでクライアントサイドレンダリングでもいいと思ってる)
今回は，ブラウザとアプリケーションサーバのやり取りだけ実装する．

## 前提の環境について

OS : Win10 Pro
node : v18.13.0
npm  : v8.19.3
express : 4.16.1


## 環境構築

### 手順1. expressgeneratorのインストールと実行

```console:expressgenerator
npm install express-generator -g
express --view=pug myapp
```
以下のようなファイル構造で出力される

```txt:出力されたファイル群
C:.
│  app.js　# 処理の根幹となるファイル
│  package.json # パッケージ情報
│
├─bin
│      www　# サーバの実行ファイル
│
├─public # クライアント側からアクセス可能なファイル群
│  ├─images 
│  ├─javascripts
│  └─stylesheets
│          style.css
│
├─routes　# 各ページの処理周りのファイル
│      index.js
│      users.js
│
└─views # 各ページの表示周りのファイル
        error.pug
        index.pug
        layout.pug
```

最後に，expressgeneratorで生成されたファイルに必要なパッケージをインストールする
```
npm install
```

### 手順2. bootstrap5をローカルインストール/ファイルを配置する

公式ページからソースをインストールする．

https://getbootstrap.jp/docs/5.3/getting-started/download/

最低限必要なもの以外は全部消す．
```
bootstrap-5.3.0-dist
├─css
│       bootstrap.min.css
│       bootstrap.min.css.map
│
└─js
        bootstrap.bundle.min.js
        bootstrap.bundle.min.js.map
```

cssは`public/stylesheets`に配置．
jsは`public/javascripts`に配置．

### 手順3. layout.pugでbootstrap5を読み込んで実装する

layout.pugにcss.jsを読み込む行を実装する．
```pug:layout.pug
doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
    link(rel='stylesheet', href='/stylesheets/bootstrap.min.css')
  body
    block content
    script(src=`/javascripts/bootstrap.bundle.min.js`)
```


cssの動作確認として，`card`(表示を整理する枠)を実装する．
知らない間にpanelsが使えなくなっていたので，こちらで実装できるように練習する．

https://getbootstrap.jp/docs/5.3/components/card/


jsの動作確認として，`carousel`(画像をスライド風に表示)を実装する．
実装例をみてちょっとおしゃれだったのでやってみようと思う．

https://getbootstrap.jp/docs/5.3/components/carousel/

`container`で，元のタイトル，カード，カルーセルを並べて表示する．
以下のように実装した，

```pug:index.pug
extends layout

block content
  .container
    .row
      .col-4 
        h1= title
        p Welcome to #{title}
      .col-4 
        .card(style="width: 25rem;")
          .card-header
            | カードのヘッダ
          ul.list-group.list-group-flush
            li.list-group-item リスト1 : しゃけ
            li.list-group-item リスト2 : らいおん
            li.list-group-item リスト3 : ふくろう
      .col-4
        .carousel.slide(data-bs-ride="carousel", id="carouseltest")
          .carousel-inner
            .carousel-item.active
              img.d-block.w-100(src="images/lion.png", alt="lion") 
            .carousel-item
              img.d-block.w-100(src="images/owl.png", alt="owl")
            .carousel-item
              img.d-block.w-100(src="images/syake.png", alt="syake")
          button.carousel-control-prev(type="button", data-bs-target="#carouseltest", data-bs-slide="prev")
            span.carousel-control-prev-icon(aria-hidden="true")
            span.visually-hidden Previous
          button.carousel-control-next(type="button", data-bs-target="#carouseltest", data-bs-slide="next")
            span.carousel-control-next-icon(aria-hidden="true")
            span.visually-hidden Next
```

.col-4で区切って上から，
1. デフォルトのタイトル表示
1. カードの表示
1. カルーセルでの表示
となっている．

実装結果はこんな感じ．
![サイト.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3600683/bb80fbd1-9e7b-767f-df4b-6d6557a05b02.gif)

見た目はおしゃれだが，公式サイトのコピペで簡単に実装できる．

## 最後に

Node.js + pugでbootstrap5を使ってみた．
初めてpugでHTML構造を書いてみたが，慣れるとあまり難しさを感じなくなった．
インデントでタグを表すので，pythonを書き慣れていたらHTMLより書きやすいと思う．