Vite4+DockerでTypescriptとSassをHMRする環境構築

## はじめに
メタップスアドベントカレンダー24日目の記事です。

先日、2022/12/9にVite 4.0.0がリリースされました🎉
そこで、DockerとViteを利用して、基本となるtypescriptやsassを
HMR・バンドル・コンパイルできる環境をハンズオン形式で構築していきます

:::note info
本ハンズオン実施時のバージョン情報
[ ホストOS Mac ]
macOS Monterey 12.5
Docker version 20.10.11
docker-compose version 1.29.2

[ yarn.lock ]
vite v4.0.1
sass 1.57.0
typescript 4.9.4
:::

## 本ハンズオンのゴール
Vite4 とDockerを使って、Viteの開発サーバーで
TypescriptとSASSを編集して、HMRできる環境を整える

※本ハンズオンでは、reactやvue及び、
プロジェクトごとに判断が必要なprettierやESLintをどう設定するか等は扱いません、
気軽な気持ちでTSとSASSを試せるローカル環境を作ることを目的としています

## Viteとは

次世代フロントエンドツールと公式で紹介されていますが、
従来Webpack等で行なっていた作業を爆速で行えるようです

https://ja.vitejs.dev/

## HMRとは
ホットモジュールリプレイスメントの略です、開発時に変更内容を自動検知して
ブラウザに変更した内容を反映させる機能です
Viteには、もちろんこの機能があります


一通り用語については押さえたので、早速ハンズオンを始めていきましょう


## 1. プロジェクトディレクトリの準備

```sh:プロジェクトディレクトリ作成
mkdir adc-vite
cd adc-vite
```
※adc = **a**dvent **c**alen**d**ar

## 2. Dockerfileとdocker-compose.ymlの準備

```sh:Dockerfileとdocker-compose.yml作成
mkdir -p docker/node
touch ./docker/node/Dockerfile 
touch docker-compose.yml
```

<br />
Dockerfileを編集

```dockerfile:[ProjectRoot]/docker/node/Dockerfile
FROM node:19.2.0-buster

WORKDIR /app

CMD ["node"]

```

<br />
docker-compose.ymlを編集

```:docker-compose.yml
version: "3.8"
services:
  adc-vite-node:
    container_name: adc-vite-node
    build:
      context: .
      dockerfile: ./docker/node/Dockerfile
    volumes:
      - ./:/app
    tty: true
    ports:
      - "3000:3000"

```

## 3. Vite のスキャフォールディングを準備
コンテナに入り、Vite関連のリソースをセットアップ

```
docker-compose build --no-cache
docker-compose up -d
docker-compose exec adc-vite-node /bin/bash

# ProjectNameはviteと入力、あとはVanilla, Typescriptを選択してエンター
yarn create vite

```

※ ↓yarn create vite 実行ログ
![001_tarncreatevite.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2990943/055cb7f9-e0a3-6a64-46b7-362d675d7549.png)



`yarn create vite` 実行後、下記を実行
```
cd vite
# 全てのパッケージと依存関係をインストール
yarn
# yarn devせずに一旦Dockerfile等を編集すべくexitしてコンテナから抜けます
exit
# 立ち上げたコンテナはdownさせます
docker-compose down
```


## 4. HMRを行うためにいくつかのファイルを追加・修正

### 下記vite.config.tsをviteディレクトリ配下に追加
```ts:vite/vite.config.ts
import { defineConfig } from 'vite'

export default defineConfig({
  server: {
    host: '0.0.0.0',
    port: 3000,
  },
})

```

### docker-compose.yml修正
4173ポートの追加を行なっているのは、yarn previewで立ち上がるプレビュー機能が
4173ポートをデフォルトで利用する為です
プレビュー機能はdistのリソース（yarn build時に作成される公開用途のリソース）を
利用して動作確認をローカルで行える機能になります

```:docker-compose.yml
version: "3.8"
services:
  adc-vite-node:
    container_name: adc-vite-node
    build:
      context: .
      dockerfile: ./docker/node/Dockerfile
    volumes:
      - ./:/app
    tty: true
    ports:
      # Port that can be checked in the browser while using HMR when running yarn dev
      - "3000:3000"
      # Port that can be checked in the browser while using HMR when running yarn preview
      - "4173:4173"
    # Start the Vite development server when the container starts
    # command: bash -c "yarn dev"

```

### Dockerfile修正
viteディレクトリが作成されているので、コンテナログイン時の作業ディレクトリを、
yarnコマンドが実行できるviteディレクトリに変更します

```diff_docker:docker/node/Dockerfile
FROM node:19.2.0-buster

- WORKDIR /app
+ WORKDIR /app/vite

CMD ["node"]

```

### Dockerfileを変更したので、コンテナ再ビルド

```
docker-compose build --no-cache
```

## 5. ここまでの作業で、ディレクトリ構成を確認

```
adc-vite/
   　|
   　├ docker/
   　|  　└ node/
   　|　 　     └ Dockerfile
   　├ vite/
   　|    ├ node_modules/
   　|    |  └ *
   　|    ├ public
   　|    |  └ vite.svg
   　|    ├ src
   　|    |  ├ counter.ts
   　|    |  ├ main.ts
   　|    |  ├ style.css
   　|    |  ├ typescript.svg
   　|    |  └ vite-env.d.ts  
   　|    ├ .gitignore
   　|    ├ index.html                  <- vite's default entry point
   　|    ├ package.json
   　|    ├ tsconfig.json
   　|    ├ vite.config.ts
   　|    └ yarn.lock
   　|
   　└ docker-compose.yml

```

## 6. 動作確認

それでは、Viteの開発サーバーを立ち上げてHMRの動作確認していきましょう

```
# コンテナ起動
docker-compose up -d
# コンテナにログイン
docker-compose exec adc-vite-node /bin/bash
# コンテナ内で実行(Viteの開発サーバーを起動）
yarn dev

```

yarn dev実行後下記のようにURLが発行されます
![002_yarn_dev.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2990943/3c5ef388-18be-97a7-88c5-ec7656eddc97.png)

localhost:3000にアクセスすると、無事Viteの画面が確認できました
![003_access.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2990943/6b6ffde8-e843-1442-0ebe-d54f42934c7f.png)

試しに、main.tsあたりを編集してみると、無事ブラウザ上に変更した内容が、
反映されました、これで実際にHMRを行えていることが確認できました
![004_HMR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2990943/06e9e0d5-26b5-c7ba-106c-377adddab337.png)

Control+cでyarn devの実行を停止させたら、次に
```
# distディレクトリに公開用のリソースが作成されます
yarn build
# distに作成された公開用リソースの確認をローカル上で行えます
yarn preview
```
を実行してみましょう
![005_yarnbuildandpreview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2990943/ebab9401-648a-4f98-a5de-5efd50377b4b.png)


yarn preview後にブラウザで確認、（※yarn preview では、HMRは行われないようです）
また、yarn previewはdist内に作成されたリソースが利用されるようです、
yarn devよりも、公開する形に近いものの確認を行うための機能と想定しています

![006_preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2990943/a9ed6ada-9d0a-fafd-c90d-577091285c65.png)


## 6. ViteからSassを扱えるようにします

### まずデフォルトではSASSのコンパイルができないことを確認していきましょう

まずは、デフォルトでsassがコンパイル出来ないことを確認します
以下ファイルを変更します

```diff_typescript:vite/src/main.ts
import './style.css'
+ import './test.scss'
import typescriptLogo from './typescript.svg'
import { setupCounter } from './counter'

document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
  <div>
    <a href="https://vitejs.dev" target="_blank">
      <img src="/vite.svg" class="logo" alt="Vite logo" />
    </a>
    <a href="https://www.typescriptlang.org/" target="_blank">
      <img src="${typescriptLogo}" class="logo vanilla" alt="TypeScript logo" />
    </a>
    <h1>Vite + TypeScript</h1>
    <div class="card">
      <button id="counter" type="button"></button>
    </div>
    <p class="read-the-docs">
      Click on the Vite and TypeScript logos to learn more
    </p>
  </div>
`

setupCounter(document.querySelector<HTMLButtonElement>('#counter')!)

```

以下SCSSファイル追加
```diff_scss:vite/src/test.scss
$bg_theme_color: orange;

body{
  background-color: $bg_theme_color;
}
```

以下コマンドを実行
```
yarn dev
```

![007_sass_compile_dailed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2990943/474dcf44-8014-3711-c1f4-8b548c2697bb.png)

デフォルトの状態だとViteでSassがまだ扱えない状態であることが、なんとなく分かりましたね
Control+c押下後に、コンテナにログインしている状態かつ、viteディレクトリにいる状態で、
下記を実行します

```
yarn add --dev sass
```

これで、SASSを解釈してコンパイルできるようになりました
もう一度viteの開発サーバーを起動させてみましょう
```
yarn dev
```

test.scssに書いた背景色が反映されました
![008_sassOK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2990943/e9267185-a102-4485-a623-452a8a92a2d4.png)


本ハンズオンは以上になります、作成したコンテナ環境が
何かの役に立つことを祈っております、今回ハンズオンで作成したものは
Githubで公開しております
https://github.com/mp-kmurahata/adc-vite

拙い文章で恐縮ですが、ここまで読んでいただきありがとうございました🍀