Nuxt.js v2.4.0がリリース🎉 TypeScriptの公式サポート、スマートプリフェッチなど。まとめてみた。

Nuxt.js v2.4.0がリリース🎉🎉🎉🎉

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Nuxt v2.4.0 is finally here 🎉<br>Official TypeScript support, smart prefetching and many more features &amp; bug fixes.<a href="https://t.co/Ljf29xYvXi">https://t.co/Ljf29xYvXi</a></p>&mdash; Nuxt.js (@nuxt_js) <a href="https://twitter.com/nuxt_js/status/1089948593392365568?ref_src=twsrc%5Etfw">2019年1月28日</a></blockquote>

**TypeScriptの公式サポート**と、**スマートプリフェッチ**がおもなトピックのようですね。

今回は、待ちに待ったプリフェッチのリリースということもあり、
がんばってdev.toを読んでみました。（英語ぜんぜん出来ません...😢。）

なんとなく読み取れましたのと笑、v2.4.0試してみましたので、
せっかくですし、まとめます！

独断でめぼしいとこだけ抜き出してますので、全文を読みたいという方は以下をどうぞ。
["Nuxt.js v2.4.0 is out! TypeScript, Smart prefetching and more..." by Sébastien Chopin ](https://dev.to/nuxt/nuxtjs-v240-is-out-typescript-smart-prefetching-and-more-18d)

それではいきますー！

# TypeScript サポート ✨
今回の目玉、公式のTypeScriptサポートです。
[nuxt-ts](https://www.npmjs.com/package/nuxt-ts)（または [nuxt-ts-edge](https://www.npmjs.com/package/nuxt-ts-edge)）でTypeScriptの使用が可能になりました！

以下のようにVueコンポーネントが書けるように。
（サンプルコード: [Nuxt TypeScript example] (https://github.com/nuxt/nuxt.js/tree/dev/examples/typescript) より引用。）

```index.vue
<template>
  <HelloWorld />
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import HelloWorld from '~/components/HelloWorld.vue'
@Component({
  components: {
    HelloWorld
  }
})
export default class Home extends Vue {}
</script>
```

```HelloWorld.vue
<template>
  <div>
    {{ message }}
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
@Component
export default class HelloWorld extends Vue {
  message: string = 'Hello world !'
}
</script>
```
より踏み込んだサンプルが見たい方は、
[HackerNews-TS repo](https://github.com/nuxt-community/hackernews-nuxt-ts) などもあるようです。

# スマートプリフェッチ ⚡️
画面の表示領域に入った `<nuxt-link>` のリンク先となるページを自動プリフェッチします。
ページ遷移の高速化により、大幅なユーザー体験向上が見込めます！
（さっそく試してみましたが、めちゃ体感いい😊）

Nuxt.js v2.4.0よりデフォルトで有効となります。

以下は、公式で用意されている比較のデモです。

-  [プリフェッチなし（Nuxt.js v2.3）](https://nuxt-no-prefetch.surge.sh/)
-  [プリフェッチあり（Nuxt.js v2.4）](https://nuxt-prefetch.surge.sh/)

**プリフェッチあり**の方をみてみましょう。
![IMG_4E1A0B96741B-3.jpeg](https://qiita-image-store.s3.amazonaws.com/0/26072/ef4f61c4-2cd7-65f6-e0df-98be22bdd0af.jpeg)
スクロールすると、画面の表示領域に入ったリンクには✅（プリフェッチ済みの印）が付いていくのがわかります。

✅のついたリンク先はプリフェッチ済みですので、
オフライン状態でも遷移が可能になっています。

また以下のように、通信状態をリアクティブに参照できるようになりました。
(サンプルコード: [Example of Nuxt.js prefetching](https://github.com/nuxt/nuxt.js/tree/dev/examples/nuxt-prefetch) より引用。)

```default.vue
<template>
　　　　...
  <div v-if="$nuxt.isOffline" class="offline">
    You are offline
  </div>
  ...
</template>
...
```
`$nuxt.isOnline` でオンラインかどうか、
`$nuxt.isOffline` でオフラインかどうか判定できます。

なお、プリフェッチの設定については `nuxt.config.js` でおこないます。

```nuxt.config.js
export default {
  ...
  router: {
    // To disable prefetching, uncomment the line
    // prefetchLinks: false

    // Activate prefetched class (default: false)
    // Used to display the check mark next to the prefetched link
    linkPrefetchedClass: 'nuxt-link-prefetched'
  }
}
```

プリフェッチをオフにする場合は、 `prefetchLinks: false` を指定。

プリフェッチ済みかどうかはclassの付与によって判定するので、
`linkPrefetchedClass:` で付与するクラス名を指定します。
（デフォルトでは、classは付与されません。）


とにかく便利なプリフェッチですが、
Google謹製のモジュール [quicklink](https://github.com/GoogleChromeLabs/quicklink) にヒントを得て開発されたとのこと。
Nuxtナシでも同様の実装は可能なようです。

quicklinkについては以下をどうぞ。（すごい簡単みたい...!?）
[quicklinkで超簡単にページロードを高速化する](https://qiita.com/szk3/items/90a187409b166919c00e)

# `store/` 以下のファイルで完全なHMRがサポート 👀
F5やリロードを押さなくても自動描画してくれるアレですね。
`mutations` や `getters` 、`actions` のコード保存時について、HMRが！

やったね！👏

# VSCodeの拡張機能Veturでオートコンプリート ✅
VSCodeユーザーに朗報です📣

Veturで、 `<nuxt-link>` 、 `<no-ssr>` などのNuxt.js独自のコンポーネントにも、
オートコンプリートしてくれるようになりました！
<img width="1648" alt="スクリーンショット 2019-01-30 14.37.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/26072/cf70bbc7-ec9c-6785-a7cf-ef12cafc02c2.png">

# 開発環境のポートの重複を解決 💪
指定したポートが他のプロジェクトで使用済みだった場合、
警告をだしてくれて...
<img width="429" alt="スクリーンショット 2019-01-30 14.59.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/26072/7a8f4dc7-9788-7149-015c-f0c01266202e.png">
(`localhost:3000` は使用済みです。)

ランダムに空いているポートでlistenしてくれます！
<img width="442" alt="スクリーンショット 2019-01-30 15.03.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/26072/9cfaa74f-98e6-1584-9622-f167c9f61cf6.png">
(`localhost:53412` でlistenしてくれました！)

本番で重複してしまった場合には、エラーをくれます。
<img width="510" alt="スクリーンショット 2019-01-30 15.30.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/26072/3c371b08-0892-fd64-588d-5e611eeb59f6.png">

# モジュールの不足やミスマッチを自動で検出 💯
インストールされているモジュールの依存関係を、Nuxtが自動的に検出します。

モジュールの不足やバージョンの不一致によるエラーなど、
問題を検出した場合には、適切なメッセージで警告してくれるようになりました。
<img width="580" alt="スクリーンショット 2019-01-30 15.50.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/26072/0c122177-5c8b-6b79-8f57-b1e3422e981a.png">
すばらしい〜〜

# pluginのモードと拡張子について 💅
ブラウザでのみ利用するプラグインについては、
SSR（サーバーサイドレンダリング）をオフにするために以下のようにしてきました。

```nuxt.config.js
export default {
  ...
  plugins: [
    { src: '~/plugins/plugin.js', ssr: false }
  ]
  ...
}
```
こちらの `ssr: false` の**オプションは廃止**され、
代わりに `mode:` オプションが導入されました。

ファイルの末尾（接尾辞）を次のように
`.server.js` 、 `.client.js` 、 `.js` とすると、

```nuxt.config.js
module.exports = {
  ...
  plugins: [
    '~/plugins/plugin.server.js',
    '~/plugins/plugin.client.js',
    '~/plugins/plugin.js'
  ]
  ...
}
```

内部で次のように展開されます。

```nuxt.config.js
module.exports = {
  ...
  plugins: [
    { mode: 'server', src: '~/plugins/plugin.server.js' },
    { mode: 'client', src: '~/plugins/plugin.client.js' },
    { mode: 'all', src: '~/plugins/plugin.js' }
  ]
  ...
}
```
（`mode:` を手動で指定した場合、接尾辞の指定は上書きされます。）

# PostCSSが使えるようになりました 💃
ほう。`lang="postcss"` で使えるようになるらしい。

```HelloPostCSS.vue
<template>
  <div class="red>
    This is red
  </div>
</template>

<style lang="postcss">
@custom-selector :--red div.red;
:--red {
  background-color: blue;
}
.red {
  color: red;
}
</style>
```
PostCSS...なるほど...？

# Stylesheetsの拡張子が不要になりました 🦅
`nuxt.config.js` 内の、 `css:` 配列にリストされている、
CSS、SCSS、PostCss、Less、Stylus などのファイルの拡張子を省略することができます。

```nuxt.config.js
module.exports = {
  ...
  css: [
    'assets/styles/app'
  ]
  ...
}
```

`plugins:` や `serverMiddleware:` はすでに省略可能でしたね。

# SSRバンドルの性能が向上しました 🔹
>SSRバンドルがどのようにパッケージされているかを全面的に書き直しました。
パフォーマンスの向上、メモリのオーバーヘッドの減少、OOMクラッシュの減少、およびSSRバンドルのデバッグの容易化を意味します。

とのことです。軽くなってる＼(^o^)／

|  -  | Before | After | Diff |
| :-: |:-:|:-:|:-:|
| Dist | 8.2M | 7.2M | -1M / 12%  |
| Dev | 281MB (RSS: 439MB)  | 237MB (RSS: 354MB) | -44M / 16% (RSS: -85M / 19%)  |
| Start | 106MB (RSS: 169MB) | 71.7MB (RSS: 137MB) | -34M / 32% (RSS: -32M / 19%) |

# その他の変更 🌔

- `<nuxt-link>` のエイリアスとして、`<n-link>` 、 `<NLink>`が利用可能に
- `<nuxt-child>` のエイリアスとして、`<n-child>` 、 `<NChild>`が利用可能に

# Nuxtのこれからについて 📎

Nuxtの将来やビジョンについては [nuxt/rfcs](https://github.com/nuxt/rfcs) にて詳しく議論がされているようです。

今後の変更については、

- Nuxtのデフォルトでオフライン対応のサイト生成をする、完全な静的生成モード
- ローカル・リモートで動くPythonのFacric的な、Vue/Nuxtのタスクランナー
- Nuxt Workersというサーバーサイドとしての機能（PM2とインテグレーションしてクラスタリング、サーバー上でHMRなど。）

等々ありました。

いまだと静的生成をしても、遷移時はリクエストをしてしまうので、
完全な静的生成モードがくるのは嬉しいですね〜
GatsbyJSチックな方向も網羅していくんでしょうか。

あとはサーバーサイドとしての可能性が、これからもっと開けていくようです。
（Nuxt Workersのところに、そんなことが書いてありました。）

リリースプラン🚢では、

- 6ヶ月ごとにメジャーリリースしていく予定
- マイナーなリリースは4週間ごと

とのことでした。これからが楽しみですねー！

# さいごに
もし間違った情報がありましたらコメント等でおしえていただけると幸いです。

Nuxt最高 🙌いつもありがとう 💚

# 追記：2019.01.31
プリフェッチのclass付与で、コンポーネントのルート要素が `<nuxt-link>` だと、
元のクラス名がおかしくなる現象があったのですが...
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Nuxt.js プリフェッチのclass付与で、元のクラス名がおかしくなる現象に...。コンポーネントのルート要素が&lt;nuxt-link&gt;なのはダメっぽい？</p>&mdash; 新田聡一郎 (@soichiro_nitta) <a href="https://twitter.com/soichiro_nitta/status/1090420421424439296?ref_src=twsrc%5Etfw">January 30, 2019</a></blockquote>
v2.4.2でfixされました。はやっ！
[Release v2.4.2 · nuxt/nuxt.js](https://github.com/nuxt/nuxt.js/releases/tag/v2.4.2)