Vue3プロジェクトをサブドメインで使う話

結構悩みましたが擦りに擦られているネタだと解決後に判明しましたw

vue3プロジェクトを作成してそのままbuildするとdistに成果物が発生しますが、それって…

サブディレクトリでは動かないのですよ!

その対策を考えたいともいます

Vue3プロジェクトの作成

vue3プロジェクトの作成はコマンド一発で作成されます

$ npm init vue@latest

Vue.js - The Progressive JavaScript Framework

- Project name: … vue-sample
- Add TypeScript? … No / Yes
- Add JSX Support? … No / Yes
- Add Vue Router for Single Page Application development? … No / Yes
- Add Pinia for state management? … No / Yes
- Add Vitest for Unit Testing? … No / Yes
- Add an End-to-End Testing Solution? › No
- Add ESLint for code quality? … No / Yes

すべてNoで作りましたw(コピペではアンダーバーが表示されないのかw)

ビルドする

はい、ビルドまでは予定調和なのでさささっと書いておきます

$ npm install

added 33 packages, and audited 34 packages in 9s

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

found 0 vulnerabilities
$ npm run build

> vue-sample@0.0.0 build
> vite build

vite v3.2.2 building for production...
✓ 23 modules transformed.
dist/assets/logo.da9b9095.svg    0.30 KiB
dist/index.html                  0.41 KiB
dist/assets/index.1da8cd0c.css   3.59 KiB / gzip: 1.17 KiB
dist/assets/index.47b3536f.js    60.91 KiB / gzip: 24.12 KiB

これで成果物がdistに展開されますのでこれをコピーしてリリースすればOKです

がっ! このままではNGでした

動作確認する

distの動作の確認はpreviewで行えます

$ vite preview
  ➜  Local:   http://localhost:4173/
  ➜  Network: use --host to expose

ブラウザでhttp://localhost:4173/にアクセスすればサンプルページが表示されます!

これで動作確認を完了していましたが、これをサブディレクトリに展開したときに動かない!

サブディレクトリの動作は、WebStormにてindex.htmlをブラウザで開けば再現されました

http://localhost:63343/vue-sample/dist/index.html

はい、開かれるのはサブディレクトリ vue-sampleに展開されます。

すると…

真っ白です…

consoleを確認すると

エラーです…

なんだか index.cssのパスが通っていない?

ソースを確認すると

<script type="module" crossorigin="" src="/assets/index.47b3536f.js"></script>
<link rel="stylesheet" href="/assets/index.1da8cd0c.css">

はい、/とルートディレクトリを指しています。
サブディレクトリ(vue-sample)なので./vue-sample/assetsにあるので動いていません;;

問題はここにあります

解決方法

解決方法はシンプルでした。

viteの払い出しのbaseをいじってやればOKです

viteの設定ファイルはvite.config.jsにありますのでその中でbaseを追記します

export default defineConfig({
  base: './', // ←これを追加
  plugins: [vue()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

これでbuildするとパスが以下のようになって動作します

<script type="module" crossorigin="" src="./assets/index.47b3536f.js"></script>
<link rel="stylesheet" href="./assets/index.1da8cd0c.css">

はい、./assetsになりました!

終いに

今回は標準のサンプルプログラムで動かないじゃないかということでメモを残しておきました。

でも、これって動きはしますが、不具合が一部あります。

不具合ってのはvue-router周りです。
現在開発はTSで行っていますが、historyだかhashだかどっちかの場合は真っ白ページになります。
RouteViewの中身が展開されません。
別の方にすれば動きますが、paramsがquerysだったりまるっきり書き方が変わりますので結構大変です。
この辺りはどうにかしたいですね

次回はもう少しvue-router周りを調べてメモを残しておきましょうかね