Nuxt2からNuxt3への移行時のメモ
はじめに
業務でNuxt2からNuxt3への移行の対応をしました。
その時に行った実際な対応内容について列挙していきます。
実際の移行対応時に困っている項目のみ見ていただければいいかなと思います。
対応時点から少し時間が経っていますので、随時記載しているリンク先のドキュメントもご参照ください。
前提
移行前のソースの大まかな構成
- Nuxt2
- Vue2
- Vuex
- Vuetify
@nuxtjs/composition-api
Nuxt2のプロジェクトでは@nuxtjs/composition-api
を利用していました。
そのため、Composition APIへの書き換え等はしていません。
(Vue3でもOption APIは利用できるのでアップグレード作業としてはそもそも不要ですが)
外部ライブラリはあまり使用していなかったため、案外スムーズに移行できましたが、Vuetifyの対応は非常に大変でした。(そもそもの仕様変更が多数)
進め方
Nuxt3のプロジェクトを新規で作成して、それをベースに既存のコードを少しずつ移行しました。
Vue
v-modelの書き方
Vue3からv-modelの仕様が変更になりました(破壊的変更)。
prop: value
-> modelValue
event: input
-> update:modelValue
Nuxt
Pages
layoutの設定
definePageMeta
が追加されたので、
糖衣構文でもlayoutを指定できるようになりました。
definePageMeta({
layout: 'sample-layout',
})
ページのタイトルの設定
headタグを指定するComposition APIのuseHead
が用意されているのでこれを使用しました。
useHead({
title: 'サンプルタイトル',
})
ルーティング
URLパラメータを使用する場合のファイル名のルールが変わりました。
pages/users/_id.vue
-> pages/users/\[_id\].vue
また、/users/* だけでなく /users でもアクセスしたい場合は以下のようにします。
pages/users/\[\[_id\]\].vue
自動インポート
Nuxt3では自動インポートの機能により、composables/
などの特定のディレクトリについてはimport
を記述することなく参照することができるようになりました。
ですが、composables/
はデフォルトではサブディレクトリが認識されないので以下の設定を追加しました。
imports: {
dirs: ['composables/**'],
},
extendRoutes
extendRoutesでのルーティングのカスタマイズは以下のように変更になりました。
export default {
router: {
extendRoutes (routes) {
//
}
}
}
export default defineNuxtConfig({
hooks: {
'pages:extend' (routes) {
//
}
}
})
Vuetify
Nuxt3用のVuetifyのモジュールが対応されていなかったため、plugins
を利用した記述に修正しました。
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)
})
各コンポーネント毎の差分は膨大な量になるため、ここでは記載しません。
Polyfill
Vueutify3はSafariやEdgeなどのブラウザの古いバージョンに対応していません。
そのためPolyfillの対応を追加しました。
app: {
head: {
script: [
{ src: 'https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver,ResizeObserver,WebAnimations,Object.fromEntries,Array.prototype.at'},
],
},
},
状態管理
状態管理にはVuexからPiniaを使用するように変更しました。
Vue3ではPiniaを公式に推奨されています。
以下のライブラリが必要です。
- pinia
- @pinia/nuxt
Composition APIと同じような書き方ができるようになったので、
非常にシンプルで使いやすくなりました。
HMR
開発の時点でhttpsを利用する場合はWebSocketのprotocolにws
ではなくwss
を設定する必要があります。
(localhostで起動する場合は設定不要)
vite: {
...
server: {
hmr: {
protocol: 'wss',
clientPort: 443,
path: 'hmr/',
},
},
},
今回はWebサーバーとしてNginxを使用しました。
その設定ファイルには以下を記述しました。
server {
...
location /_nuxt/hmr/ {
proxy_pass <http://sample-app:24678>;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Web Worker
Web Worker用のloaderは不要になりました。
以下のようにWorkerのインスタンスを生成は以下のような記述にしました。
(worker.jsファイルのimportは不要)
// URLの第一引数にはソース上のパスを記載
this.worker = new Worker(new URL('./worker.js', import.meta.url), {
type: 'module',
})
Discussion