SolidJSのアプリをGithub Pagesで公開する

# はじめに
注目が高まりつつあるフレームワーク、SolidJSを自分も試してみたい！　と思い立ち、どうせなら他の人にも見える形でいじっていこうとGitHub Pagesで公開することを考えていたのですが、すんなり行かなかったのでメモ的に手順を投稿しました。

SolidJS特有の詰まりポイントというわけではないため、viteベースの他のフレームワークの新規プロジェクトをGitHub Pagesで公開したいという方にも参考になるかもしれません。

# 手順
## SolidJSの新規プロジェクトを立ち上げる
SolidJSの新規プロジェクトを立ち上げは[公式ドキュメント](https://www.solidjs.com/guides/getting-started)を参考にしました。
適当なディレクトリーに移動してから以下のコマンドでテンプレートプロジェクトを立ち上げます。
(% 以下を実行してください)

```zsh
% npx degit solidjs/templates/ts my-app
> cloned solidjs/templates#HEAD to my-app

% cd my-app
% npm i

added 92 packages, and audited 93 packages in 9s

8 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
```

ここまででテンプレートの新規プロジェクトが立ち上がったので、ローカルで起動してみます。
```zsh
% npm start

> vite-template-solid@0.0.0 start
> vite


  VITE v4.3.7  ready in 350 ms

  ➜  Local:   http://127.0.0.1:3000/
  ➜  Network: use --host to expose
  ➜  press h to show help
```

`http://127.0.0.1:3000/`にアクセスすると以下のような画面が出てくるので、テンプレートプロジェクトができたことが確認できます。
本記事の最終的な目標はこの画面をGitHub Pagesで公開することですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/b63f0593-675b-fd69-9bc2-569d1198f3e7.png)

ここで一旦SolidJS側の作業は終了とし、GitHub側の設定に入ります。

## GitHubにPushする
各々の方法でお使いのGitHubにPushしてください。
私は[GitHub Desktop](https://desktop.github.com/)というアプリでGitの管理をしており、結構便利なのでそちらを用いた方法をお勧めすることが多いです。

ここでは、リポジトリー名は`solidjs-test`で作成しました。

:::note warn
注意: 公開する都合上、リポジトリーの設定はPublicにしておく必要があります。
:::

まずはリポジトリーを作成して、
```zsh
% git init
Initialized empty Git repository in /Users/**/my-app/.git/
```

GitHub Desktop側では `Add Existing Repository`してからPublishすればOKです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/0b362e0e-5033-22ae-5ae6-42ca8865d233.png" width="50%">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/926babb6-cc42-b3e8-d44e-733672fe6353.png" width="50%">

これでリモート側にPushできました。

## GitHub Pagesを有効化する
Pushした後、GitHubのリポジトリーを開くと以下のような画面になっていると思います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/6aa423eb-2bd6-de8c-7f49-8653a04957f8.png">


`Setting` > `Pages` と選択していけば以下の表示になります。
もしここでリポジトリーがPublicになっていない場合は別の表示になっていると思いますので先に公開設定に変更してください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/c463fee6-f691-f84e-a014-4215bce014da.png">

以下のように、
`Deploy from a branch` > `main` > `/(root)` と(とりあえず)設定しておき、
`save`ボタンを選択するとデプロイがはじまります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/b32f955f-ca3f-7602-4200-e92275604175.png" width="80%">


しばらくしてから画面をリロードすると以下のように表示が変わり、準備が完了していることがわかります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/e2573ebb-e8ce-3452-9ead-47dddde74487.png" width="80%">

しかし、アクセスしてみると以下のように真っ白でまだうまく表示できていないことがわかります。
コンソールを確認するとリソースがうまく取得できていないようですね。

というわけでここからはSolidJSで作成したプロジェクトをGitHub Pagesで表示するために設定に変更を加えていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/7f130cf1-20ec-59a1-fd6d-6b4d2674aa13.png)


## GitHub Pages用に変更を加える
主に必要な変更箇所は以下の通りです。
### (1) SolidJSアプリのビルド
そもそもの話として、GitHub Pagesは静的ページのホスティングサービスです。
ローカルで確認するだけならviteで開発サーバーを立ち上げれば済む話ですが、公開するコードはソースをビルドする必要があるわけですね。

まずはビルドを行います。
SolidJSのデフォルトの設定ではビルドされたファイルは/distに格納されるようになっていますが、GitHub Pagesの参照ディレクトリー設定は`/(root)`と`/docs`の二つしかありません。
したがって、そこを変更してあげる必要があります。
設定する項目は`vite.config.ts`内にあります。
```diff_typescript:vite.config.ts
import { defineConfig } from 'vite';
import solidPlugin from 'vite-plugin-solid';

export default defineConfig({
  plugins: [solidPlugin()],
  server: {
    port: 3000,
  },
  build: {
    target: 'esnext',
+   outDir: './docs',
  },
});
```
build設定の部分に`outDir: './docs'`を追加することで、吐き出されるファイルが/docs以下に格納されるようになります。

設定を変更したらビルドします。
```zsh
% npm run build                       

> vite-template-solid@0.0.0 build
> vite build

vite v4.3.7 building for production...
✓ 9 modules transformed.
docs/index.html                    0.59 kB │ gzip: 0.36 kB
docs/assets/logo-123b04bc.svg      1.60 kB │ gzip: 0.55 kB
docs/assets/favicon-0e726a38.ico  15.09 kB
docs/assets/index-ba74b708.css     0.71 kB │ gzip: 0.47 kB
docs/assets/index-f795380f.js      7.34 kB │ gzip: 3.16 kB
✓ built in 253ms
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/993f8660-e96b-c47c-dc4c-978186f875b2.png" width="50%">

最終的にdocs以下にビルドされたファイルが格納されたはずです。
これでビルドの手順は終了です。

### (2) GitHub Pagesの参照元変更

GitHub Pages側の変更は、`/(root)`にしていた部分を`/docs`に変えて`save`でデプロイするだけです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/aa54ed31-1721-4122-05a0-cc8a123e15aa.png" width="80%">


しかしながらここまで変更してプッシュしても、紹介した手順通りに作成してきている場合まだアプリは表示できません。
さらにもう一箇所変更が必要な部分があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/ce4bbc5a-9255-eace-72d8-9501283bbfa1.png)


### (3) SolidJSアプリのbase URLの変更
GitHub Pagesの仕様で、リポジトリー名に`<user>.github.io`のような指定された形式の名前をつけた場合には`https://<user>.github.io/`にデプロイされるためいまから実施する変更は不要になりますが、それ以外の場合は`https://<user>.github.io/<リポジトリー名>/`にデプロイされることになります。
そのため、そのままでは`https://<user>.github.io/`の`/docs`を探そうとしてしまうため、`base`を変更して`https://<user>.github.io/<リポジトリー名>/`から参照してやるように変更する必要があります。

`base`の設定は`vite.config.ts`で行います。
リポジトリー名に`solidjs-test`以外を設定している場合、この部分は適宜変更してください。

```diff_typescript:vite.config.ts
import { defineConfig } from 'vite';
import solidPlugin from 'vite-plugin-solid';

export default defineConfig({
  plugins: [solidPlugin()],
  server: {
    port: 3000,
  },
  build: {
    target: 'esnext',
    outDir: './docs',
  },
+ base : "/solidjs-test/",
});
```

## デプロイ成功！
この状態で再度ビルドし直して、GitHubに変更をプッシュしてください。
しばらくするとGitHub Pages側に反映されて以下のように目的の画面が表示されていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/5bb9d4d8-8e6c-1d36-45fa-b02e29a19591.png)


# おまけ
ここまでやってきて、勘の良い方は
「これ毎回ビルドしてデプロイする手順踏まないといけないのか……面倒だな」
とお気づきの方もいらっしゃると思います。
本筋とは直接関係がないため最後に持ってきましたが、GitHub Actionsを利用すればプッシュにトリガーしてビルドを実行してくれるワークフローを作成可能です。
つまり、いちいちローカルでビルドせずともプッシュするだけで公開ページが更新されるようにできます！

## GitHub Actionsでビルドを自動化
`Settings` > `Pages` > `Source`を`Deploy from a branch`から`GitHub Actions`に変更 > `Static HTML`を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/5f5af10b-7e60-e5a5-be60-ac711431a54e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3410763/537cbad0-5bf9-130a-2530-3e1e697f39a6.png)

名前は適当でいいので、テンプレートとして用意されているstatic.ymlを以下のように変更します。

```yml: build-pages.yml
name: Build and Deploy static content to Pages

on:
  push:
    branches: ['main']
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: 'pages'
  cancel-in-progress: true

jobs:
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Set up Node
        uses: actions/setup-node@v3
        with:
          node-version: 18
          cache: 'npm'
      - name: Install dependencies
        run: npm install
      - name: Build
        run: npm run build
      - name: Setup Pages
        uses: actions/configure-pages@v3
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v1
        with:
          path: './docs'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v1
```

これを`Commit changes...`して保存すれば手順は終了です。
以降Pushするたびにこのworkflowが走って自動でビルド・デプロイしてくれるようになります。


# 参考記事
https://www.solidjs.com/

https://zenn.dev/thetalemon/articles/3c55a60a1de6ae

https://qiita.com/tonio0720/items/c28b4d37e6ab860ea04d

https://ja.vitejs.dev/guide/static-deploy.html