Nuxt3で実務想定の実装環境を構築する

# TL;DR
実際に案件で使うであろうモジュールを導入して、
実務用の環境整備を行うための手順メモです。

# 今回使えるようにするもの
- Nuxt3
- Scss
- TypeScript
- ESLint
- Storybook
- Vitest

# 手順
## Nuxt3のインストール
```console
$ npx nuxi init プロジェクト名
$ cd プロジェクト名
$ npm i
```

### ディレクトリ構成
こういうかんじにしたい（再考中）

```console
.
├── README.md
├── node_modules
├── nuxt.config.ts
├── package-lock.json
├── package.json
├── public
│   └── favicon.ico
├── src
│   ├── assets // 画像やcssを入れる
│   ├── components
│   │   ├── AComponentName // プリミティブな基本コンポーネント
│   │   │   ├── AComponentName.vue // コンポーネント
│   │   │   └── AComponentName.stories.vue // コンポーネントのストーリー
│   │   │
│   │   └── ComponentSet // プリミティブを組み合わせたコンポーネントセットの分類
│   │       ├── componentModule
│   │       ├── ComponentItem.vue
│   │       ├── ComponentItem.stories.vue
│   │       ├── ComponentList.stories.vue
│   │       └── ComponentList.spec.ts // 単体テスト
│   │
│   ├── layouts
│   │   └── layout.vue
│   ├── middleware
│   ├── modules // 共用モジュール
│   │   └── module.ts
│   ├── pages // ページルーティング
│   │   └── page.vue
│   ├── plugins
│   └── store
└── tsconfig.json
```

### 設定
```nuxt.config.ts
export default defineNuxtConfig({
  srcDir: "src/", // コンポーネントの置き場所を変更
  vite: { // バンドラーをViteに変更
    server: {
        watch: {
            usePolling: true
        }
    },
  }
})
```

### デフォルトで使える主なもの
- Typescript
- VueUse
    - lodashとか含まれてるっぽい便利ツール
- ビルドツール系
    - Vite
    - Webpack
- ホスティング系のCLI
    - Azure
    - Cloudflare
    - Netlify
    - Versel

### 利用できるコマンド一覧
```console
// ビルド
$ npm run build
$ npx nuxt build

// 開発サーバー起動
$ npm run dev
$ npx nuxt dev

// SSG
$ npm run generate
$ npx nuxt generate

// ビルド後のプレビュー
$ npm run preview
$ npx nuxt preview
```
## Scss
https://pankobo.me/blog/post/202207-nuxt3-scss

### インストール
```console
$ npm i -D sass
```

### 設定
```nuxt.config.ts
export default defineNuxtConfig({
  // 略
  css: ['@/assets/styles/main.scss'],
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@import "@/assets/styles/variables.scss";'
        }
      }
    },
    // 略
  }
})
```



## ESLint
https://zenn.dev/rescuenow/articles/e39b8272439f1a

こちらに書かれていること丸っと。

### インストール
```console
$ npm i -D @nuxt/eslint-config eslint
$ npm i -D @nuxtjs/eslint-config-typescript
```

### 設定
プロジェクトルートに設定ファイル作成
```/.eslintrc.yml
root: 
  true
extends: 
  - "@nuxtjs/eslint-config-typescript"
```

package.jsonに実行コマンド追記
```/package.json
{
  "scripts": {
    "lint": "eslint --fix 'src/**/*.{ts,vue}'"
  }
}
```

### VSCode側の設定
VSCodeのマーケットプレースで拡張機能の`ESLint`をインストールする
VSCodeの`settings.json`に以下内容を追加する

```settings.json
{
    "editor.codeActionsOnSave": {
        "source.fixAll": false,
        "source.fixAll.eslint": true
    }
}
```

## Storybook
https://qiita.com/fsd-ssk/items/dbc32c7ac1259d3c2857

### インストール
```console
$ npx sb init --type vue3 --builder @storybook/builder-vite
$ npm i -D @storybook/addon-postcss // globalなcssを読み込むのに必要
```

```.storybook/main.js
const { mergeConfig } = require('vite')

module.exports = {
  "stories": [
    "../src/**/*.stories.mdx",
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
    // main.jsを読み込むための準備
    {
      name: '@storybook/addon-postcss',
      options: {
        postcssLoaderOptions: {
          implementation: require('postcss'),
        },
      },
    }
    // main.scssを読み込むための準備ここまで
  ],
  "framework": "@storybook/vue3",
  "core": {
    "builder": "@storybook/builder-vite"
  },
  "features": {
    "storyStoreV7": true
  },
  // 環境変数・mixinはここでインポートする
  viteFinal: async (config) => {
    return mergeConfig(config, {
      css: {
        preprocessorOptions: {
          scss: {
            additionalData: `
            @use "../src/assets/styles/variables.scss" as *;
              `,
          },
        },
      },
    })
  },
  // 環境変数・mixinのインポートここまで
}
```

```.storybook/preview.js
// globalなcssを読み込む
import '../src/assets/styles/main.scss'

/* 以下略 */
```


### 実行
```console
$ npm run storybook
```

### ビルド
```console
$ npm run build-storybook
```

## Vitest
https://zenn.dev/ytr0903/articles/8f4e3c0e529c6f

### インストール
```console
$ npm i -D vitest unplugin-auto-import
```

### 設定
```vitest.config.ts
import { defineConfig } from "vitest/config"
import Vue from "@vitejs/plugin-vue"
import AutoImport from "unplugin-auto-import/vite"

export default defineConfig({
  plugins: [
    Vue(),
    AutoImport({
      imports: ["vue"]
    })
  ],
  test: {
    globals: true,
    environment: "jsdom"
  }
});
```

```package.json
{
  "scripts": {
    "test": "vitest"
  }
}
```

### 実行
```console
$ npm run test
```

# サンプルコード
https://github.com/rockinruuula1227/nuxt_sample

上記リポジトリにコミットしています。
nuxt-sample_v3のディレクトリで以下のコマンドを流すとサンプルページが確認できます。

```console
$ npm ci
$ npm run dev
```

![d5a7f0b7-e0ee-45ec-5ca3-b22e74362ca1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288273/c079dcde-a69a-ed2e-5baf-922c09f0350e.png)

Storybookも閲覧可能です。

```console
$ npm run storybook
```
![356843fe-c48e-58c0-dd49-fc02732d89c6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288273/58595078-d31f-58b0-f899-3921508fa175.png)