Skip to main content

Vue3×ViteでのSSRをサクッと試してみた

· 4 min read

Vue3 と Vite(ヴィート)を使って SSR(サーバサイドレンダリング)を試してみた。 Vite は Vue や React のビルドツールだが、その機能を使って SSR が実現できるとのこと。

Server-Side Rendering | Vite

※現在 Experimental な機能となっているため、本番運用では使わないようにしたほうが良い。破壊的変更があるかもしれないので。

Vue3 プロジェクトの作成​

とりあえずまずは Vue3 のプロジェクトを作成する

yarn create vite --template vue-ts

プロジェクト名を適当に vue-ssr-app とかにする

yarn install しておく

cd vue-ssr-app
yarn install

試しに起動

yarn dev

localhost:3000 にアクセスし、developer tool で Doc を確認すると、Response に App.vue の内容が記載されていないとが分かる。 つまり、SPA モードで起動しており、JS によってレンダリングが実行されている。

起動することは確認できたので、以下より SSR を行っていく

SSR 化​

以下の step で SSR 化を行う

  1. ssr に必要なプラグインのインストール
  2. SSR プラグインの読み込み
  3. ページ用コンポーネントの作成
  4. App.vue の修正
  5. router の作成
  6. main.ts の修正
  7. ssr モードで起動

ssr に必要なプラグインのインストール​

SSR 化するために必要なプラグインをインストールする

yarn add vite-ssr vue-router@4 @vueuse/head

@vueuse/head は title 等の head 内の属性を設定するためのもの、これを使うと簡単に meta 情報が設定できる

SSR プラグインの読み込み​

SSR プラグインの読み込み

vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import SSR from 'vite-ssr/plugin'

export default defineConfig({
plugins: [vue(), SSR()]
})

ページ用コンポーネントの作成​

top ページに配置するページコンポーネントを作成

nuxt のように pages というディレクトリを作ってみた

src/pages/Root.vue

<script lang="ts" setup>
import { useHead } from '@vueuse/head';

useHead({
title: 'Vite SSR Title'
});

</script>

<template>
Hello Vite SSR!
</template>

シンプルに文字だけを表示するとする。 useHead でタイトル属性の付加した

App.vue の修正​

この後 vue router で設定する内容を App.vue 内に流し込むコードを記述するだけ

src/App.vue

<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'

</script>

<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />

<RouterView v-slot="{ Component }">
<Suspense>
<component :is="Component" />
</Suspense>
</RouterView>
</template>

<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

router の作成​

router を作成する。/にアクセスしたとき Root.vue が呼ばれるようなシンプルなルート

src/router.ts

import { RouteRecordRaw } from 'vue-router';

export const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'ROOT',
component: () => import('/src/pages/Root.vue')
},
];

main.ts の修正​

src/main.ts

head 属性をロードしたり、SSR の設定を行ったりする

import { createHead } from '@vueuse/head';
import { viteSSR } from 'vite-ssr/vue';

import { routes } from '/src/router';

import App from '/src/App.vue';

const Options: Parameters<typeof viteSSR>['1'] = {
routes,
pageProps: {
passToPage: false
},
};

export default viteSSR(App, Options, async (params) => {
const { app, initialState, isClient, router } = params;
const head = createHead();

app.use(head);

return {
head
};
});

ssr モードで起動​

最後に package.json の dev コマンドを以下のように修正

"dev": "vite-ssr",

これで起動してみると、

yarn dev

Response に Root.vue で記述した「Hello Vite SSR!」があるので、SSR 化されていることが分かる

nuxt や next を使うともっと楽に SSR 化することはできるが、Vue3 のみで作ってきた SPA のアプリケーションを SSR 化したいときは、このような方法を試すと良いかもしれない。ただ実験的機能なので本番導入は見送り。

vite の ssr の issue も頻繁に上がっているっぽい。

https://github.com/vitejs/vite/issues?q=is%3Aissue+is%3Aopen+ssr+