Nuxt3を0から勉強した学習フローをまとめてみた


はじめに
-------
CYBIRD Advent Calendar 2022の24日目担当の@min1osです。
23日目は@R_araiさんの「VS Codeに PlantUMLを入れて設計書を作った シーケンス図編」でした。

自分は最近簡単なものは[Mermaid](https://mermaid.js.org/#/)でつくっていますが、PlantUMLは昔から使われているので覚えておくととても便利ですね。

概要
----------------
2022年11月、待ちに待った[Nuxt3](https://nuxt.com/)がようやくリリースされました。
とある案件で当初夏頃リリース予定のNuxt3がいいのでは...ということになり技術習得する必要がでてきたため、
今回はNuxt3を0から学んだ流れについてご紹介してみたいと思います。

ちなみに自分のスキルセットとしては、下記のように初めはほぼ分からないことだらけでした。

* 🔺 Vue3 - 少し触ったことがある
* ❌ Nuxt - 知らない
* 🔺 TypeScript - 昔挫折した経験/JSはjQueryで思考停止
* ⭕️ HTML/CSS - 何年かHTMLコーダーの経験あり

1.ざっくりどういうものかを調べる
------------------------------------

Nuxt3はJavascriptを用いたWebアプリケーションを開発するためのフレームワークです。
(よく比較されるものでReactを用いた[Next.js](https://nextjs.org/) があります)

モジュールバンドラでは[webpack](https://webpack.js.org/)が有名ですが、
デフォルトでは[Vite](https://ja.vitejs.dev/)が搭載されています。(どちらも使用できるらしいです)
Viteは名前の由来となったフランス語の早いを意味する`/vit/`の通り、起動速度・更新がとても早く、ホットロードも効くため効率的な開発ができます。

Webフロントでは [Vue3](https://v3.ja.vuejs.org/)を利用でき、ある程度慣れは必要ですがTypeScriptを用いて開発することになるかと思います。

まだリリース前だったためかネット上の記事が多いわけでなく
何やら良さそうだけど難しそうな印象を持ちました。

詳しい特徴については公式サイトがとてもわかりやすくまとめてくれていますのでなんとなく雰囲気は掴んでおくといいかなと思います。

https://nuxt.com/docs/getting-started/introduction

2.Nuxt3の特性を理解する
----------------

Nuxt3リリース前は公式ドキュメントも充実していなかったのですが、
今だととてもわかりやすいのでまずは一通り読み進めることをお勧めします。

https://nuxt.com/

### レンダリングモードの選定

サーバー構成を設計するため、まずはNuxt3のレンダリングモードをどうするか決めました。

Nuxt3では下記のモードが利用できます。

* Client-side Only Rendering(CSR)
* Universal Rendering

メリット・デメリットを理解した上で選定するといいかなと思います(サーバーの選定や費用感も加味するといいでしょう)

https://nuxt.com/docs/guide/concepts/rendering

Nuxt3では`nuxt.config.ts` の`ssr: false` や、`yarn build` `yarn generate` を利用するだけで簡単にレンダリングモードを切り替えることができます。

各クラウドサービスへのデプロイ方法も紹介されているのでこの辺りをも参考にするといいかなと思います。

https://nuxt.com/docs/getting-started/deployment#supported-hosting-providers

開発時の注意点として、クライアントだけ・サーバーだけで実行させたい処理やプラグインもある場合(たとえば、`window` オブジェクトへの操作) ロジックの切り分けが必要になります。

プラグインなどの場合は、`.clinet.ts` をつけると自動でクライアントだけで動作するようになるのでとても便利です。

vueファイル上で切り分ける場合は 環境変数`process.client` などを利用するといいかなと思います。(注意点としてSSGモードの場合は環境変数がないと動作しません)

``` vue
<script lang="ts" setup>
if (process.client) {
    // clientで実行したい処理
}
if (process.dev) {
    // ローカル環境で実行したい処理
}
</script>
```

Nuxt3自体はFrameworkになるため、この時点で深く理解する必要はなく
どういった機能があるのかをドキュメント全体読み解くといいかなと思いました。

特に `Auto-Imports` が入っているので、特定のディレクトリに設置することで `import`を書かなくてもいいのはとても開発が楽になります。 

https://nuxt.com/docs/guide/concepts/auto-imports

### ESモジュール

現在多くの主要ブラウザで採用されているJSのモジュールシステムがNuxt3では標準採用されています。
よくわからない人は、これまで`CommonJS`で使用した`require()`の代わりに `import`で実装することになることを注意しましょう。
(ネット記事でもCommonJS方式で紹介していることが多いため)

また、例えば外部のパッケージが`CommonJS` で記載していた場合はそのまま使用できないことを理解しておく必要があります。(簡単に入れれると思わないこと)

この辺も公式がとてもよくまとめてくれています(なかなか難しいところではありますが見ておくといいでしょう)

https://nuxt.com/docs/guide/concepts/esm


後述で説明している通りNuxt3はTypeScriptも標準使用されているのですが、有名なパッケージには `@typesパッケージ`と言われる型定義ファイルも公開していることが多いので外部パッケージを利用している場合は一緒にインストールしましょう。

https://typescript-jp.gitbook.io/deep-dive/type-system/types

``` bash
# lodashの例
yarn add @types/lodash -D
```

### assetsとpublic

Nuxt3ではCSS、画像などの置き場は`assets`と`public`があります。
`assets`はSSGモードの場合、preloadされるようなので特徴を踏まえてどちらにおくべきか考える必要があります。(基本的には`assets`はアプリケーションシェル部品をおくようにしています)

https://nuxt.com/docs/getting-started/assets

また、assetsはキャッシュバスティング(ファイル名がビルドごとにランダムになる)を採用しておりimgタグなどの静的なパスが自動的に置換されるようですので、
動的なパスについては`public`におくといいでしょう。

``` vue
<script lang="ts" setup>
// これだと動かない
const color = 'red';
const assetsImgUrl = `~/assets/images/btn-${color}.png`;
// これだと問題ない
const publicImgUrl = `/public/images/btn-${color}.png`;
</script>
```

3.言語仕様を学習する
----------------

Nuxt3はTypeScriptで実装すると良さそうだったので
私は[サバイバルTypeScript](https://typescriptbook.jp/) をベースにまずは言語仕様について学習しました。

jQuery信者だった自分には最初かなりハードルが高かったのですが、`interface`、 `class`、 `ユニオン型`や`type` などを駆使すると開発がスムーズになります。
(特に新規案件などは仕様変更が多く破壊的な改修もあるため、バグ検知しやすい印象です)

公式では[Visual Studio Code](https://nuxt.com/docs/getting-started/installation)をVue用のプラグインと共に紹介しています。
特にこだわりがなければこちらを使用することで、コーディング中のエラー検知にも役立ちます。

``` vue
<script lang="ts" setup>
// 例 未定義のプロパティでエラーになる
interface Hoge {
    name: string;
}
const hoge: Hoge = { name: 'Dummy' };
hoge.firstName = 'Dummy';   // <- エラー
</script>
```

注意点として、デプロイ時には***トランスパイル***(TypescriptのコードからJSコードに変換)されることを理解しておきましょう。

また、初心者のうちはすぐにTypeScriptでビルドエラーになるのでなかなかストレスが溜まりやすいです。(この辺で精神崩壊しかけました)

慣れないうちは実装を進める上で***全てを完璧に記載する必要はない***と思います。(`any`型や型指定なしなどやむをえない部分もあると思います)

適度に使用して少しずつ理解していくのがコツかなと思います。

4.Vue3の仕様を理解する
----------------

Nuxt3でフロントUIを構成する基礎となる技術がVue3だと思います。

単純にネット検索するとVueの古い記述方法の `Option API` と `Composition API` が出てきますが、 [Composition API](https://v3.ja.vuejs.org/api/composition-api.html) で記載していくことになるかなと思います。(できることは同じで記述方法が違う認識でいます。詳しくは下記を参照してください)

https://v3.ja.vuejs.org/guide/composition-api-introduction.html

ただ、[Vue3のドキュメント](https://v3.ja.vuejs.org/)では `Option API` がまず紹介された上で `Composition API` が紹介されているためごっちゃにならないように気をつける必要があります。
(ここは慣れるまで大変でした)
一通りOption APIでできることを調べた上でComposition APIで進めるといいかなと思います。

ここまでである程度実装できるようになると思いますが、Vue3で便利だったことも紹介しておきます。

### scriptタグはsetup、styleはscopedを使用する

この辺りは下記ミスがあると挙動が変わるため注意が必要です。
特に、styleのscopedはグローバルにCSSが展開されるため他のページ・コンポーネントへの影響が考えられます。
わからないうちは必要な場合を除きとりあえずつけておきましょう。

``` vue
<script lang="ts" setup>
</script>
<style lang="scss" scoped>
</style>
```

### HTMLElementも実はref取得できる

jQueryだと`$('#scrollView').scrollTop` とかで取得できたものがVue3でもできます。

``` vue
<template>
<div>
  <div ref="scrollView" />
</div>
</template>

<script lang="ts">
const scrollView = ref<HTMLDivElement>();

await nextTick(() => {
  const top = scrollView.value?.scrollTop;
});
</script>
```

### 変数をCSSに渡せる

`:root` でCSS変数に設定すると色々と便利です。

``` vue
<script lang="ts">
const redColor = ref("#FF0000");
const height = ref("100px");
</script>

<style lang="scss" scoped>
:root {
  --red: v-bind(redColor);
}
.text {
  color: var(--red);
  height: v-bind(height);
}
</style>
```

5.Nuxt3の今後に期待
----------------

Nuxt3はまだ正式にリリースされたばかりですが、モジュールが豊富です。
下記にてプロジェクトにあったモジュールを検索できます。

https://nuxt.com/modules

また、***Nuxt2とNuxt3は別もの*** であることを認識しておきましょう。
(Nuxt2のモジュールはNuxt3では動かないと思います)

今後リリース予定(元々2022年夏リリースのはずだったのだが、、、)のもので個人的に期待しているのが [Nuxt-PWA](https://pwa.nuxtjs.org/)のNuxt3バージョンになります。

端末の機能などを利用するケースでは [VueUse](https://vueuse.org/) などもおすすめです。


まとめ
----------------

最初慣れないとなかなか難しいところがありますが、1,2ヶ月ほど触ると理解が進むと思います。

特に新しい領域の技術習得は覚える単語が多く、初めはストレスがたまりやすいと思いますが根気よく頑張っていきましょう。

個人的にはNuxt3はかなり満足していますので、皆さんもぜひ触ってみてください。

明日のCYBIRD Advent Calendar 2022 最終日は、@S_onizawaさんの「アルゴリズムを知ろう」です！
お楽しみに！