はじめに
今回この構成を使用するに至ったのは、ハッカソン形式のチーム開発で「Webで動作する2次元ゲーム」を作成することになったことがきっかけです。
その際、TypeScriptを用いた環境構築と、GitHub Pagesのデプロイを実施したのですが、複数ファイルの取り込み→GitHub Pages公開までの記事がなかった(あったとしてもReact
やVue
などのフレームワーク限定)ので、今回は記事を上げさせていただきました。
-
JS
→TS
で書きたいが、デプロイまでの構築が分からない -
React
やVue
ではない、純粋なHTML
+TS
での開発に慣れている
これらを実施したい人がターゲットになります!
事前にnode
がインストールされており、npm
コマンドが使用できる前提で話を進めていきます
Viteはtsでの効率的な開発&buildツール
開発は型変換のあるtsファイルで実施し、Buildして最終的にjsファイルに変換し、静的コード(SSG)としてビルドします。これらを簡単に行えるのがViteというツールです。
似たようなツールとしてWebPackなどもありますが、あれは難しすぎますね。
HTML + TS環境の構築(Vite)
viteのセットアップ
既にセットアップしている人は飛ばして大丈夫です。npx create-vite
から実施する方法もありますが、初期ファイルだと少し理解しにくい部分があるので、不安な方は以下のファイルをコピペしてください。
package.json
{
"name": "my-project-name",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"devDependencies": {
"typescript": "^5.2.2",
"vite": "^5.3.1"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
vite.config.ts
import { defineConfig } from "vite";
export default defineConfig({
server: {
open: true,
},
});
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + TS</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
- src/main.ts(こちらは空のままで大丈夫です)
npm i # パッケージのインストール
npm run dev # localhostで起動
これで、最低限のファイルで起動構成をセットアップすることができました。実際に、今後はindex.htmlやmain.tsをいじることで、HTML + JSと同じような感覚で開発ができるようになります。
その他、画像やcssファイルは、publicディレクトリにいれてください。
複数ページの実装
本記事の目標である、複数ページのデプロイです。具体的には、
/ (ホーム画面)
/select (選択画面)
/game (プレイ画面)
のように、複数のページを用意するイメージです。これがReactであればrouter-dom
を使用することでReactファイルのコードにわかりやすく記載が可能ですが、今回はシンプルにViteのみを使用するので別の書き方が必要になります。
ファイル構成
.
├── game # /game に対応するファイル
│ └── index.html
├── public
│ ├── images
│ │ ├── android-1440x2560-wallpaper_02132.jpg
│ │ ├── bad.png
│ │ ├── good.png
│ │ ├── great.png
│ │ ├── miss.png
│ │ └── perfect.png
│ └── styles # CSS files
│ ├── select.css
│ ├── game.css
│ └── index.css
├── select # /select に対応するHTML
│ └── index.html
├── src # ts files
│ ├── game.ts
│ ├── index.ts
│ └── select.ts
├── index.html # / に対応するHTML
├── package.json
├── tsconfig.json
└── vite.config.ts
上記のようにするだけで、npm run dev
で起動すると/
, /select
, /game
にそれぞれアクセスできます。
index.htmlが不格好に記載されていますが、私が試した限り、/
以降のルーティングがそのまま配置されてしまうため、もう少しスッキリまとめられる方法ありましたらご教示いただけると嬉しいです。
HTML内のPATHは/
, tsは/src
以降に
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>トップ画面</title>
<!-- CSSの読み込み -->
<link rel="stylesheet" href="/styles/index.css" />
</head>
<body>
<div>
<p>Joken音ゲー</p>
<button class="GO">START</button>
</div>
<!-- JSの読み込み -->
<script src="/src/index.ts" type="module"></script>
</body>
</html>
CSSは/public
直下にフォルダが配置されているので、ビルド時にもファイルが保存されます。今回の場合は/
から始まったパスを入力することで反映されます。
tsファイルだけは、/src
をつけて読み込みます。ビルド後は/assets
フォルダにコンパイル済みのjsが保存され、HTML内のパスもきちんと変更されます。/
から読み込んでいるので、/select/index.html
なども同様のパスで読み込んでOKです。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>トップ画面</title>
<link rel="stylesheet" href="/styles/index.css" />
<!-- パスが書き換わってる -->
<script type="module" crossorigin src="/assets/main-UY9zy4Kc.js"></script>
<link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-B5Qt9EMX.js">
</head>
<body>
<div>
<p>Joken音ゲー</p>
<button class="GO">START</button>
</div>
<!-- tsの読み込みは削除されている -->
</body>
</html>
複数ページのビルド
しかしこれだけでは、ビルド時はindex.html
しかコンパイル、ビルドされません。これを解決するには、vite.config.ts
を編集します。
import { defineConfig } from 'vite';
export default defineConfig({
build: {
rollupOptions: {
input: {
// ここにパス一覧を記述
main: 'index.html',
game: 'game/index.html',
select: 'select/index.html',
},
},
},
});
inputの中、左側のmain
やgame
などは好きな名前で大丈夫です。右側のパスは/
直下からのパスを間違いなく入力してください。
これを記述するだけでビルド時に対象のHTML、TSがきちんとコンパイル、ビルドされるようになります。
GitHub Pagesにデプロイする
次はデプロイです。GitHub Pagesにデプロイをすることで、自身でドメイン・サーバーを契約することなくWebサイトを公開できます。
手順は以下のとおりです。
-
gh-pages
のインストール -
package.json
の編集 -
vite.config.ts
の編集 - GitHub Pagesの設定
gh-pagesのインストール
npm i --save-dev gh-pages
gh-pagesは、新たにgh-pages
というブランチを作成し、そこにbuildしたファイルを上げるまでを自動で行うツールです。GitHub Pagesは、buildしたgh-pages
ブランチを公開する流れとなります。
package.jsonの編集
以下の2行を追加します。
{
"homepage": "https://<自身のGitHubアカウントID>.github.io/<リポジトリ名>/", ←この行を追加
"scripts": {
"deploy": "gh-pages -d dist" ←scriptsの中に追加
}
}
実際にデプロイをする際は、
npm run build
npm run deploy
をすることで、gh-pages
ブランチのファイルが最新の状態にビルドされて更新されます。
vite.config.tsの編集
import { defineConfig } from 'vite';
export default defineConfig({
base: '/<リポジトリ名>/', // ←この行を追加
build: {
rollupOptions: {
input: {
main: 'index.html',
game: 'game.html',
select: 'select.html',
},
},
},
});
baseを追加することで、URLが/
から/<リポジトリ名>/
を含むようになり、GitHub Pagesのルーティングに最適化されます。index.html
に記載のcss
, ts
などのパスは/
, /src
のままで編集する必要ありません。
GitHub Pagesの設定
Settings
> Pages
に移動し、Branchを指定してセーブしてみましょう。
設定が完了すると、gh-pages
が更新された際にデプロイのプロセスが自動で行われ、最終的に公開されます。
これで、GitHub Pagesのデプロイが完了しました。