Nuxt を v2 から v3 にアップグレードする

あまり Nuxt3 ( Vue3 ) を触ってきておらず時代に取り残されつつあったので、個人で書いてた Nuxt プロジェクトを v2.15 系から v3.5 系にアップグレードします。
元々のプロジェクトがかなりシンプルな構成だったので、意外とすんなりいきました。

備忘録を残します。
Nuxt3 が動くようになるところまでなので、細かいコードの変更などはこの記事には記載していません。

# Upgrade Nuxt to v3

まずは Nuxt3 を入れます。

```bash
$ npm i nuxt@3
```

このままだと既存の `Vue` と import が干渉して

```
[vite-node] [plugin:vite:import-analysis] [VITE_ERROR] /app.vue
```

のようなエラーが出るので `vue` を削除します。

```diff_javascript: package.json
 {
   // ...
   "dependencies": {
     // ...
-    "vue": "^2.7.10",
     // ...
   }
   // ...
 }
```

Nuxt3 を init から生成すると、以下の package がデフォルトで入るようなので追加します。


```diff_javascript: package.json
 {
   // ...
   "dependencies": {
     // ...
+    "@nuxt/devtools": "latest",
+    "@types/node": "^18",
     // ...
   }
   // ...
 }
```

DevTools については以下を参照ください。

https://devtools.nuxtjs.org/

また、`nuxt.config.js` ( `.ts` ) の書き方が変わるようなので修正します。

https://nuxt.com/docs/migration/configuration

> You should migrate to the new defineNuxtConfig function that provides a typed configuration schema.

```diff_javascript: nuxt.config.js
-export default {
+import { defineNuxtConfig } from "nuxt/config";
+
+export default defineNuxtConfig({
+  // devtools の機能を使いたい場合は以下も追加
+  devtools: { enabled: true },
   // ...
-}
+})
```

( なくても動くみたいですが ) init からプロジェクトを生成した場合だと、`/public` と `/server` というディレクトリがデフォルトで用意されるみたいなので配置しておきます。

```bash
$ mkdir public server
```

作成した `/server` ディレクトリに `tsconfig.json` を配置します。

```typescript: server/tsconfig.json
{
  "extends": "../.nuxt/tsconfig.server.json"
}
```

init から生成すると `/public` ディレクトリにはデフォルトで `favicon.ico` が入ってくるみたいですが、Nuxt2 系の `static/` に入ったままでも大丈夫みたいです。

# Remove `@nuxtjs/axios`

Nuxt 3 では Axios 使わないらしいので削除。

```diff_javascript: package.json
 {
   // ...
   "dependencies": {
     // ...
-    "@nuxtjs/axios": "^5.13.6",
     // ...
   }
   // ...
 }
```

```diff_javascript: tsconfig.json
 {
   // ...
   {
     // ...
     "types": [
       // ...
-      "@nuxtjs/axios",
       // ...
     ]
     // ...
   }
   // ...
 }
```

```diff_javascript: nuxt.config.js
 export default {
   // ...
   modules: [
     // ...
-    // https://go.nuxtjs.dev/axios
-    '@nuxtjs/axios',
     // ...
   ],
   // ...
-  // Axios module configuration: https://go.nuxtjs.dev/config-axios
-  axios: {
-    // Workaround to avoid enforcing hard-coded localhost:3000: https://github.com/nuxt-community/axios-module/issues/308
-    baseURL: '/',
-  },
   // ...
 }
```

# Remove `@nuxtjs/style-resources`

`@nuxtjs/style-resources` が Nuxt3 に対応していないようなので入っていたら削除。

```diff_javascript: package.json
 {
   // ...
   "dependencies": {
     // ...
-    "@nuxtjs/style-resources": "^1.2.1",
     // ...
   }
   // ...
 }
```

```diff_javascript: nuxt.config.js
 export default {
   // ...
   modules: [
     // ...
-    '@nuxtjs/style-resources',
     // ...
   ],
   // ...
-  styleResources: {
-    scss: ['@/assets/path/to.scss'],
-  },
+  vite: {
+    css: {
+      preprocessorOptions: {
+        scss: {
+          additionalData: '@import "@/assets/path/to.scss";',
+        },
+      },
+    },
+  }
   // ...
 }
```

# Remove `@nuxt/typescript-build`

Nuxt3 はデフォルトで TypeScript をサポートしているので Build Module を削除します。

```diff_javascript: package.json
 {
   // ...
   "devDependencies": {
     // ...
-    "@nuxt/typescript-build": "^2.1.0",
     // ...
   }
   // ...
 }
```

```diff_javascript: nuxt.config.js
 export default {
   // ...
   buildModules: [
     // ...
-    // https://go.nuxtjs.dev/typescript
-    '@nuxt/typescript-build',
     // ...
   ],
   // ...
 }
```

# Remove `@nuxtjs/composition-api`

Vue 2 系のために Composition API module を使っている場合は、これも不要になるので削除します。

```diff_javascript: package.json
 {
   // ...
   "dependencies": {
     // ...
-    "@nuxtjs/composition-api": "^0.33.1",
     // ...
   }
   // ...
 }
```

```diff_javascript: nuxt.config.js
 export default {
   // ...
   buildModules: [
     // ...
-    '@nuxtjs/composition-api/module',
     // ...
   ],
   // ...
 }
```

`@nuxtjs/composition-api` を使っている箇所を修正します。

```diff_vue: *.vue
 <template>
   <!-- ... -->
 </template>

 <script lang="ts">
 // ...
-import { defineComponent } from '@nuxtjs/composition-api'
+import { defineComponent } from '@vue'
 // ...
 </script>
```

# Fix import path for global css 

global な CSS の設定が相対パスだと読み込みエラーになるようになったみたいなので修正します。

```diff_javascript: nuxt.config.js
 export default {
   // ...
   // Global CSS: https://go.nuxtjs.dev/config-css
-  css: ['./assets/scss/reset.scss', './assets/scss/base.scss'],
+  css: ['@/assets/scss/reset.scss', '@/assets/scss/base.scss'],
   // ...
 }
```

# Run Nuxt3!!!!

root ディレクトリに `app.vue` を追加します。

```vue: app.vue
<template>
  <div>
    <NuxtPage />
  </div>
</template>
```

以下のコマンドを実行して、localhost にアクセスできれば成功。

```bash
$ npx nuxi dev
```

... Vue3 系で Reactive なオブジェクトへのアクセス方法が変わっているため、

```
TypeError: hoge.value.fuga.split is not a function
```

のようなエラーが出ます。
これを解決するために Vue コードの修正は必要ですが、Nuxt3 へのアップグレード自体はこれで完了です。

お疲れ様ですた。