コンテンツにスキップ

Nuxt.js v3 のインストール + 初期設定

Nuxt の v3 インストール方法と初期設定について自分用にまとめたものです。
Nuxt をインストールしたあと、Vuetify もいれます。さらに PWA 化もします。

環境

  • nuxt: 3.0.0
  • vuetify: 3.0.5
  • sass: 1.57.0
  • eslint: 8.30.0
  • eslint-plugin-nuxt: 4.0.0
  • @nuxtjs/eslint-config-typescript: 12.0.0

スタータープロジェクトを入れる

npx nuxi init <PROJECT-NAME> でスタータープロジェクトを作成します。
Yarn を使う場合でも、npx で作成するしかないようです。

<PROJECT-NAME> ディレクトリの下に、以下のファイルが生成されます。

  • .gitignore
  • app.vue
  • nuxt.config.ts
  • package.json
  • README.md
  • tsconfig.json

その後、プロジェクトのディレクトリに入り yarn install で依存パッケージをダウンロードします。
@types/node のインストールも忘れずに。

yarn install
yarn add -D -E @types/node

ちなみに、当然 package.json には name とかの基本設定が書かれていないので、書き加えるのを忘れずに。

基本的な設定

  • meta タグ
  • components ディレクトリとかを src ディレクトリに置きたいのでソースディレクトリを src にする
  • 型チェックは NODE_ENVdevelopment のときのみ行う
  • stricttrue
nuxt.config.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
const baseName = process.env.BASE_NAME || "example-app";
const baseDescription = process.env.BASE_DESCRIPTION || "Example app";
const baseUrl = process.env.BASE_URL || "https://example.com";
const isDev = process.env.NODE_ENV === "development";
const isSsr = true;

export default defineNuxtConfig({
  app: {
    head: {
      htmlAttrs: {
        lang: "ja",
      },
      meta: [
        { name: "viewport", content: "width=device-width, initial-scale=1" },
        { name: "apple-mobile-web-app-title", content: baseName },
        { name: "application-name", content: baseName },
        { name: "msapplication-TileColor", content: "#1d9bf0" },
        {
          name: "msapplication-config",
          content: baseUrl + "/favicons/browserconfig.xml",
        },
        { name: "theme-color", content: "#1d9bf0" },
        { key: "description", name: "description", content: baseDescription },
        { key: "og:site_name", property: "og:site_name", content: baseName },
        { key: "og:type", property: "og:type", content: "article" },
        { key: "og:url", property: "og:url", content: baseUrl },
        { key: "og:title", property: "og:title", content: baseName },
        {
          key: "og:description",
          property: "og:description",
          content: baseDescription,
        },
        {
          key: "twitter:card",
          name: "twitter:card",
          content: "summary",
        },
        {
          key: "msapplication-TileColor",
          name: "msapplication-TileColor",
          content: "#00aba9",
        },
        {
          key: "msapplication-config",
          name: "msapplication-config",
          content: baseUrl + "/favicons/browserconfig.xml",
        },
        {
          key: "theme-color",
          name: "theme-color",
          content: "#1da1f2",
        },
      ],
      link: [
        {
          rel: "apple-touch-icon",
          sizes: "180x180",
          href: baseUrl + "/favicons/apple-touch-icon.png",
        },
        {
          rel: "icon",
          type: "image/png",
          sizes: "32x32",
          href: baseUrl + "/favicons/favicon-32x32.png",
        },
        {
          rel: "icon",
          type: "image/png",
          sizes: "16x16",
          href: baseUrl + "/favicons/favicon-16x16.png",
        },
        {
          rel: "mask-icon",
          href: baseUrl + "/favicons/safari-pinned-tab.svg",
          color: "#5bbad5",
        },
        {
          rel: "shortcut icon",
          href: baseUrl + "/favicons/favicon.ico",
        },
      ],
      noscript: [{ children: "This website requires JavaScript." }],
    },
  },

  srcDir: "src/",

  ssr: isSsr,

  typescript: {
    typeCheck: isDev,
    strict: true,
  },
});

src ディレクトリに app.vue を移動すること。

eslint

yarn add -D eslint eslint-plugin-nuxt @nuxtjs/eslint-config-typescript vite-plugin-eslint

package.json にこのへんのスクリプトを追加。

package.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare",
    "lint": "eslint --ext .js,.ts,.vue --ignore-path .gitignore .",
    "lintfix": "eslint --ext .js,.ts,.vue --ignore-path .gitignore . --fix"
  }
}

さらに nuxt.config.ts に以下の設定を追加。

nuxt.config.ts
1
2
3
4
5
6
7
8
const isDev = process.env.NODE_ENV === "development";

export default defineNuxtConfig({
  vite: {
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    plugins: [isDev ? require("vite-plugin-eslint")() : undefined],
  },
});

eslint の設定は Nuxt v3 での eslint 設定 を参照。とりあえずは以下。

.eslintrc.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
root: true
env:
  browser: true
  es2021: true
  node: true
parserOptions:
  ecmaVersion: latest
  sourceType: module
extends:
  - '@nuxtjs/eslint-config-typescript'
  - plugin:@typescript-eslint/recommended
  - plugin:vue/vue3-recommended
  - plugin:nuxt/recommended

prettier は使わないので、.prettierignore に以下を記述。

.prettierignore
1
**

Vuetify

yarn add -D vuetify @mdi/font sass

nuxt.config.tsbuildcss に以下の設定をします。

nuxt.config.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
export default defineNuxtConfig({
  build: {
    transpile: ["vuetify"],
  },

  css: [
    "vuetify/lib/styles/main.sass",
    "@mdi/font/css/materialdesignicons.min.css",
  ],
});

さらに、プラグインとして Vuetify の初期設定を src/plugins/vuetify.ts に追加します。

src/plugins/vuetify.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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)
})

PWA

公式の PWA モジュールは v3 に対応していないっぽいので、v2 と互換性のある非公式の PWA モジュールを利用します。

で、nuxt.config.tsmodules に定義します。
また、このモジュールはメタデータを引き継がないようなので、以下の通り PWA 用に設定する必要があります。

nuxt.config.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const baseName = process.env.BASE_NAME || "example-app";
const baseDescription = process.env.BASE_DESCRIPTION || "Example app";
const baseUrl = process.env.BASE_URL || "https://example.com";
const siteColor = "#1d9bf0";

export default defineNuxtConfig({
  modules: ["@kevinmarrec/nuxt-pwa"],

  pwa: {
    manifest: {
      name: baseName,
      short_name: baseName,
      description: baseDescription,
      lang: "ja",
      theme_color: siteColor,
      background_color: siteColor,
      display: "standalone",
      start_url: "/",
    },
    meta: {
      name: baseName,
      description: baseDescription,
      theme_color: siteColor,
      lang: "ja",
      mobileAppIOS: true,
    },
  },
});

Pinia

Nuxt.js v2 で利用されていた Vuex はバンドルされなくなり、開発者が状態管理ライブラリを選択できるようになった(らしい)。

2021 年 6 月ごろには Vuex 5 の情報があったのだが、このディスカッション によれば Pinia が Vue における公式状態管理ライブラリという位置付けらしいので、これを使うことにします。

なお、状態の永続化をするため @pinia-plugin-persistedstate/nuxt を利用します。

まず、普通にパッケージをインストールします。

yarn add pinia @pinia/nuxt @pinia-plugin-persistedstate/nuxt

次に、まあ例のごとく nuxt.config.tsmodules に追記します。

nuxt.config.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
export default defineNuxtConfig({
  modules: [
    ['@pinia/nuxt',
      {
        autoImports: ['defineStore', 'acceptHMRUpdate']
      }
    ],
    '@pinia-plugin-persistedstate/nuxt'
  ]
});

あとは Nuxt 3 における新しい state と同様に、useState を使って状態を定義します。

src/store/settings.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
export const useSettingsStore = defineStore('settings', {
  state: (): {
    hoge: string
    fuga: boolean
  } => ({
    hoge: "hogehoge",
    fuga: false,
  }),

  // getter をつくることもできる
  // getters: {},

  actions: {
    setHoge(hoge: string) {
      this.hoge = hoge
    },
  },

  persist: {
    storage: persistedState.localStorage
  }
})

presist.storage には localStorage のほかに sessionStorage, cookies が指定可能な様子。

そして、状態を使う場所で以下のようなコードを書きます。

1
2
3
4
5
6
import { useSettingsStore } from '../store/settings'

const settingsStore = useSettingsStore()

const hoge = settingsStore.hoge
settingsStore.setHoge("hogefugapiyo")