LoginSignup
3
1

More than 1 year has passed since last update.

Nuxt3+Vuetify3+mswでモックアップアプリを作る

Posted at

ちょっとしたWebアプリのモックアップを作る案件があったため、せっかくなので色々と最新のバージョンを盛り込んで構築したメモ。

  • Nuxt 3 (執筆時点で3.0.0-rc.12)
    • Vue 3やviteを使ってみたかった
  • Vuetify 3 (執筆時点で3.0.0-beta.14)
    • とりあえず新しそうだったため
  • Mock Service Worker (msw)
    • 通信部分は本物っぽく作り、モックアップではダミーサーバー、後々本物のAPIサーバーに置き換えたい。少し調べた所、mswが良さそうだったので採用。

プロジェクト生成

最近のフレームワークは一発で空プロジェクトを作れるので楽。Nuxt3はnuxiコマンドを使う。

$ npx nuxi init my-app-name

生成したmy-app-nameディレクトリをVSCodeで開いて開発を行う。
開いたら、ひとまずyarn installを実行する。

$ yarn install

なお、VSCodeでフロントエンド(Vue)開発をする際にはこのあたりの拡張機能をインストールしておけば良いはず。

  • Volar
  • ESLint
  • Prettier
  • EditorConfig

テスト起動

以下で開発サーバーを起動。

$ yarn dev

ブラウザーで http://localhost:3000/ を開く。
image.png

警告の修正

アプリのエントリポイントであるapp.vueを開くと、Volarの警告が表示された。
image.png

将来のバージョンでは表示されないかもしれないが、ここではひとまず言われた通りに@types/nodeのバージョンを固定しておく。

$ yarn add -D @types/node@18.8.0

上記を実行後、VSCodeを再起動すると警告は表示されなくなった。

Vuetify 3の追加

NuxtにVuetifyを追加する場合、yarnでパッケージを追加した後、NuxtにVuetifyを初期化させるフックとしてplugins/にファイルを追加する。
Nuxt3でもこの部分は変わっていないようだが、plugins/以下のファイルが自動認識されるためnuxt.config.tsへの追記が不要になっている。

参考にさせて頂いた記事:
https://zenn.dev/one_dock/articles/ab6d178741956d

パッケージの追加

$ yarn add vuetify@next mdi
$ yarn add -D sass

plugins/vuetify.ts

import { createVuetify } from "vuetify"
import * as components from "vuetify/components"
import * as directives from "vuetify/directives"

export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
    components,
    directives,
  })

  nuxtApp.vueApp.use(vuetify)
})

なお、このタイミングで、セミコロンなしのコーディングスタイルが好みだったのでPrettierの設定ファイルを作成した。

.prettierrc

{
  "semi": false
}

また、組み込みのCSSとトランスパイル処理を認識させるために以下の設定を追加する。

nuxt.config.ts

export default defineNuxtConfig({
    css: ["vuetify/lib/styles/main.sass", "mdi/css/materialdesignicons.min.css"],
    build: {
      transpile: ["vuetify"],
    },
})

以上でVuetifyの設定は完了なので、試しにapp.vueを書き換えてボタンでも置いてみる。

app.vue

<template>
  <div>Hello, Vuetify</div>
  <v-btn color="blue-grey" prepend-icon="mdi-magnify">SEARCH</v-btn>
</template>

image.png

mswの設定

Nuxt3で通信を行う際はuseFetchを使うのが一番簡単そうに見えた。

ボタンをクリックした際に通信を行う処理を書いてみる。

app.vue

<template>
  <div>Hello, Vuetify</div>
  <div>data: {{ jsonData }}</div>
  <v-btn color="blue-grey" prepend-icon="mdi-magnify" @click="onClick"
    >SEARCH</v-btn
  >
</template>

<script setup lang="ts">
const jsonData = useState("jsonData", () => ({}))
const onClick = async () => {
  const { data } = await useFetch("/api/search")
  jsonData.value = data.value
}
</script>

この状態でボタンをクリックすると、/api/searchはSPAのパスとしてルーティングされてしまうため、jsonDataにHTML文字列が格納されて表示される。
image.png

mswの設定を行い、/api/searchが適当なJSONを返すようにする。
msw関連のファイルはmocks/に配置することとする(任意)。

参考にさせて頂いた記事:
https://tech.smartshopping.co.jp/nuxt_with_mock_service_worker

ライブラリのインストール

$ yarn add -D msw

mocks/api/search.ts
APIが返す(ダミーの)レスポンスをコードとして書く。

import { ResponseResolver, MockedRequest, restContext } from "msw"

const get: ResponseResolver<MockedRequest, typeof restContext> = (
  _req,
  res,
  ctx
) => {
  return res(
    ctx.status(200),
    ctx.json([
      // ここがダミーのJSONデータ
      {
        message: "Hello",
      },
    ])
  )
}

export default { get }

mocks/handlers.ts
mocks/api/以下のファイルをURLと関連付ける。

import { rest } from "msw"
import search from "@/mocks/api/search"

export const handlers = [rest.get("/api/search", search.get)]

mocks/browser.ts
ブラウザーで起動するService Workerを定義する。
(SSRを使う場合はNode.js側のService Workerも定義するらしいが、割愛。)

import { setupWorker } from "msw"
import { handlers } from "./handlers"

export const worker = setupWorker(...handlers)

plugins/msw.ts
mswの初期化フック。前述の通り、このファイルを作成するだけでNuxtから認識される。

import { worker } from "@/mocks/browser"

export default () => {
  worker.start()
}

public/mockServiceWorker.js
mswのサービスワーカーがGET /mockServiceWorker.jsして使うライブラリ。
以下のコマンドで作成する。

$ mkdir public
$ npx msw init public/ --save=false

nuxt.config.ts
今回はモックアップとしてビルド成果物をHTTPサーバーに配置する想定なので、SSRを無効化する。

// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
  css: ["vuetify/lib/styles/main.sass", "mdi/css/materialdesignicons.min.css"],
  build: {
    transpile: ["vuetify"],
  },
  ssr: false,  // 追加
})

以上でmswが有効化され、画面のボタンクリック時に実際のHTTPリクエストの代わりにソースコードで定義されたダミーデータが取得されたような動作となる。
image.png

また、この状態でyarn generateで生成したstaticなビルド成果物をnginx等のWebサーバーに設置し、単独で動作させることが可能である。
将来的にはmsw.tsworker.start()if (process.env.NODE_ENV === 'development') {}で囲む等で本物のAPIサーバーと併用することもできるようだ。

3
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
3
1