0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

viteSSGとvue3で静的ページをhostingで公開

Posted at

vitePressでもいいのですが、基本を勉強しようとVue3とViteSSGを使って静的ページの生成をやります。

目的

  • WebpackやViteでMarkdownからHTMLの書き出しをしてたのでVueでもやりたい
  • hostingサービスで使えるページを生成
  • LPやコーポレートサイトにVueの便利さを追加したい
  • コンポーネントを使いまわしたい
  • ページのロード遅延を少なくしたい
  • 画像やCSSの圧縮したい

参考

Node

node -v 22.2.0

クイックスタートでvue3を開始

npm create vue@latest

ターミナルの指示に従って適切な環境を作成する。
個人的には以下。

✔ Project name: … vue-project
✔ Add TypeScript? …  Yes
✔ Add JSX Support? … No 
✔ Add Vue Router for Single Page Application development? … Yes
✔ Add Pinia for state management? … No
✔ Add Vitest for Unit Testing? … No
✔ Add an End-to-End Testing Solution? › No
✔ Add ESLint for code quality? … No
✔ Add Vue DevTools 7 extension for debugging? (experimental) … No
  • TSは使いたい
  • vue構文で記述するのでJSXは不要
  • 下層ページを作るのでvue-routerは必要
  • データ保存が必要な場合は、SSGしないのでPiniaは不要
  • 簡単なページなので、テストは不要。複雑な場合は必要
  • ESlintは後で独自にいれるので不要
  • DevToolsはどっちでもいいが、Pinia使ってないしSSGだけなら不要

ESLintとPrettierとVSCode

VScodeのESLintが保存時に遅延して保存できないissueがあるので、無効化した。

代わりにRun on Saveで保存時にpackage.jsonのnpm run lintを実行する。

packageのアップロード(注意)

npm-check-updatesで全部のpackageをアップロードする。ESLint8から9への更新は注意する

ncu

以下の更新がある

 @rushstack/eslint-patch    ^1.8.0  →  ^1.10.4
 @types/node              ^20.14.5  →  ^22.5.4
 @vitejs/plugin-vue         ^5.0.5  →   ^5.1.3
 eslint                    ^8.57.0  →  ^9.10.0
 eslint-plugin-vue         ^9.23.0  →  ^9.28.0
 npm-run-all2               ^6.2.0  →   ^6.2.2
 prettier                   ^3.2.5  →   ^3.3.3
 typescript                 ~5.4.0  →   ~5.6.2
 vite                       ^5.3.1  →   ^5.4.4
 vue                       ^3.4.29  →   ^3.5.4
 vue-router                 ^4.3.3  →   ^4.4.4
 vue-tsc                   ^2.0.21  →   ^2.1.6

Run ncu -u to upgrade package.json

ESLint9への更新

ESLint8からESLint9は破壊的な更新なので、注意。ESLint10にflat構文が基準になるので、新しくサービスを作成するならESLint9を勉強しておく

typescriptは5.4で止めとく

@typescript-eslint/typescript-estree.がWARNINGを出す

WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.

You may find that it works just fine, or you may not.

SUPPORTED TYPESCRIPT VERSIONS: >=4.7.4 <5.6.0

typescript5.6にupgradeした場合、npmでは削除してから入れ直す

npm rm typescript
npm i -D typescript@5.4  

ESLint9のセットアップ

npm init @eslint/config@latest

ターミナルの指示に従って適切な環境を作成する。
個人的には以下。

✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · vue
✔ Does your project use TypeScript? · typescript
✔ Where does your code run? · browser, node
The config that you've selected requires the following dependencies:

eslint, globals, @eslint/js, typescript-eslint, eslint-plugin-vue
✔ Would you like to install them now? · No / Yes
✔ Which package manager do you want to use? · npm

eslint.config.jsが作成される。eslint.config.tsと変更してts化。
vueのセットアップで作成された、.eslintrc.cjsがあったら不要なので削除。eslint-plugin-vueや他のpackageがセットアップ時にはいるので@vue/eslint-config-prettier@vue/eslint-config-typescriptも不要になる。あるとESLint9をサポートしてないので、Errorになる

run lintの追加

"lint": "eslint --fix 'src/**/*.{js,ts,vue}'"

src配下のファイルだけlintをかける
WARNINGが出た場合には、上記のtsのダウングレードする

firebase の設定(任意)

hostingだけなので、パッケージのインストールはない

firebase init

ViteSSGなのでFrameworkは使用しない
hostuingを選択して、projectを選択
チームメンバーがいるならgithubワークフローも追加
viteのbuildはdistフォルダに追加されるのでfirebase.jsonを書き換える

{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}

パッケージインストールしてvueの起動を確認

npm install
npm run dev

viteSSGと便利なPlugin追加

npm i -D vite-ssg
npm i -D vite-plugin-vue-layouts vite-plugin-pages unplugin-vue-router unplugin-vue-markdown critters @unhead/vue vue-gtag vite-ssg-sitemap autoprefixer vite-plugin-compression vue-cookie-accept-decline @macropygia/vite-plugin-imagemin-cache

vite-plugin-vue-layouts // unheadのmetaでlayout設定
vite-plugin-pages // pagesフォルダ内のファイルをpageComponentとして設定
unplugin-vue-router // viteSSGのvue-routerのErrorを解消
unplugin-vue-markdown // Markdownを使えるように
critters // inline CSS化
@unhead/vue // metaタグをpageコンポーネントから設定
vue-gtag // Analyticsの追加
vite-ssg-sitemap // サイトマップの自動生成
autoprefixer // 言わずもがな
vite-plugin-compression // gzip圧縮
@macropygia/vite-plugin-imagemin-cache // 画像圧縮
vue-cookie-accept-decline // GDPR対応

viteSSGとPluginの設定

READMEを見ながら始める
https://github.com/antfu-collective/vite-ssg

packageのbuildをvitSSGに変更

"build-only": "vite-ssg build",

main.tsのcreateAppをViteSSGに変更。typesは適切に追加

main.ts
import './assets/main.css'

import { ViteSSG } from 'vite-ssg'
import App from './App.vue'

import { setupLayouts } from 'virtual:generated-layouts'
import { routes } from 'vue-router/auto-routes'
import VueGtag from 'vue-gtag'
import { createHead } from '@unhead/vue'
import VueCookieAcceptDecline from 'vue-cookie-accept-decline'

const ga = 'G-XXXXXXXXXXXXXXX'

export const createApp = ViteSSG(
  App,
  { routes: setupLayouts(routes) },
  ({ app, router, routes, isClient, initialState }) => {
    app.use(VueGtag, {
      config: { id: ga, },
    }, router),
    createHead(),
    app.component('vue-cookie-accept-decline',
      VueCookieAcceptDecline)
  },
)
vite.config.ts
import { fileURLToPath, URL } from 'node:url'

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

import ViteSSGOptions from "vite-ssg";
import VueRouter from 'unplugin-vue-router/vite'
import Layouts from 'vite-plugin-vue-layouts';
import Pages from 'vite-plugin-pages'
import generateSitemap from 'vite-ssg-sitemap'
import imageminPlugin from '@macropygia/vite-plugin-imagemin-cache'
import viteCompression from 'vite-plugin-compression';
import Markdown from 'unplugin-vue-markdown/vite'
import autoprefixer from 'autoprefixer'

const hostname = "https://example.com";
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    VueRouter(),
    vue(),
    Layouts(),
    Pages(),
    Markdown({}),
    imageminPlugin(),
    viteCompression(),
  ],
  css: {
    devSourcemap: true,
    postcss: {
      plugins: [
        autoprefixer({}),
      ]
    }
  },
  ssgOptions: {
    dirStyle: "nested",
    script: "async",
    formatting: "minify",
    format: "esm",
    onFinished: () => {
      generateSitemap({
        hostname: hostname,
        exclude: []
      })
    },
    crittersOptions: {
      preload: 'media',
    },
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})
App.vue
<script setup lang="ts">
import { RouterView } from 'vue-router'
</script>

<template>
  <router-view v-slot="{ Component, route }">
    <component :is="Component" :key="route" />
  </router-view>
</template>

ここまで設定したら、buildしてみる。hostingで動くかも確認

npm run build

以上で基本的な設定は終了です。

ViteSSGはabout/index.vueabout.html変換するので、dirStyle: "nested",を追加すると、about.vueabout/index.vueabout/index.vueに書き出してくれる。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?