Nuxt.js 2.4 で変わったこと
公式リリースノートより一部抜粋していきます。
(※スクリーンショットはそれぞれ公式より引用させていただいております。)
ref: https://github.com/nuxt/nuxt.js/releases/tag/v2.4.0
TypeScriptに対応
- やったね!! 公式に TypeScript サポートが開始されました
- 内部的には
ts-loader
とfork-ts-checker-webpack-plugin
が使用されています -
Nuxt.js 内部の Webpack は js から優先的に依存を解決しようとするので同名の js と ts が存在する場合は注意
- 必要な場合は module か config で extendBuild の仕組みを使用して Webpack に設定されている定義順を入れ替えましょう
prefetch に対応
ref: https://nuxtjs.org/api/components-nuxt-link
- nuxt-link を使用している場合、dev.to みたいにページの先読みがされるようになりました。
- 実装は google/quicklink.js を参考にしたそうです。
- 意図的に prefetch を無効化するときは nuxt-link に
no-prefetch
を設定しましょう。
- プリフェッチなし (v2.3): https://nuxt-no-prefetch.surge.sh
- プリフェッチあり (v2.4): https://nuxt-prefetch.surge.sh
Store が HMR に対応
- Hot Module Replacement に Vuex が対応し、ストアのコードをいじっても初期化されなくなりました
Vetur サポートの強化
- VSCode で Vetur を使用している場合、Nuxt オリジナルの関数やメンバーが補完されるようになりました
生成されるBundleの省サイズ化
- bundle が小さくなることはいいこと!
モード | v2.4以前 | v2.4以降 | サイズ差 |
---|---|---|---|
Dist | 8.2M | 7.2M | -1M / 12% |
Dev | 281 MB (RSS: 439 MB) | 237 MB (RSS: 354 MB) | -44M / 16% (RSS: -85M / 19%) |
Start | 106 MB (RSS: 169 MB) | 71.7 MB (RSS: 137 MB) | -34M / 32% (RSS: -32M / 19%) |
その他にもいろいろ!
- nuxt-link が n-link で使えるようになりました
- 内部で使用される Webpack のバージョンが新しくなりました
- プラグインの読み込み時に拡張子ベースで Server Only / Client Only を設定できるようになりました
- 開発モードでデフォルトのポートが使用中の場合ランダムなポートを変わりに使用するようになりました
この他にもたくさん機能追加、改修がされています
ref: https://github.com/nuxt/nuxt.js/releases/tag/v2.4.0
アップグレードまでの道
担当しているプロジェクトで Nuxt.js v2.4 にするに当たり実施した改修などなどをご紹介します。
前提知識
プロジェクトの構成は下記のようになっています。
- 使用しているパッケージ
- TypeScript 3.1.x
- Nuxt.js v2.3.x
- Express 4.16.x
- Vuetify 1.4.x
- nuxt.config を含む全てのスクリプトを TypeScript で記載
普段どおりのアップデート方法
パッケージ更新を普段の運用に組み込んでいて、下記のように実施しています。
基本的に package-lock.json を一度破棄して、最初から生成し直し依存パッケージをすべて更新しています。
# ロックを解除
rm -rf node_modules package-lock.json
# パッケージを更新できるものはすべて更新
ncu -a
# 型定義ファイルの追加を検知
typesync
# オリャー!!
npm install
Nuxt.js 2.4 にして起こった問題
普段であれば、上記の手順であとは動作チェックと細かい追従対応を行い対応を完了していますが、今回は少し大きめに変更を加える必要がありました。
- 今まで通っていたビルドが大量にimportエラーを吐いてコケた
- 今まで問題のなかった箇所でSSRでDOMの不整合が発生するようになった
- .nuxt/router.js 内部での Unexpected token error
エラーの例
大量に起こったimportエラーについて
原因
- 正体は単一ファイルコンポーネント(SFC)の style ブロック内部の
url('~/assets/hoge.svg')
- 画像の読み込みが v2.3 までと微妙に異なる様子...
解決策
- 【解決策】CSS 内部では
~assets
を使いましょう - 英語版マニュアルに下記のように記載があります
- 日本語版マニュアルにもちょっと控えめに書いてありました
-
css-loader のアップグレードにより、Nuxt v2.0 から CSS のデータ型 では、~assets(スラッシュなし)を使わなければなりません。例:background: url("~assets/banner.svg")
-
SSRのDOMの不整合
原因
- 正直良くわかりませんでした。。。
- SSR の差分検知のロジックに変化があったか、そもそもいままでの書き方が悪かった可能性が高い
-
vue-server-renderer
の更新で直るかもしれない(?)
解決策
- 【解決策】必要に応じて
<no-ssr>
を使いましょう - DOMの不整合が起きている箇所のうち、差分検知ができている場合は、開発モードの場合のみヒントになる情報が検証ツールで出ています。
- CSSのセレクタやDOMの構造を頼りに問題箇所を特定して根本的に直すか、工数的に難しい場合などは
<no-ssr>
を活用しましょう。
.nuxt/router.js の Unexpected token error
原因
これが一番困った...
下記のIssueをにたどり着きどうやら npm のバグによるものらしく、パッケージの依存解決に失敗する場合がある様子。
- https://github.com/nuxt/nuxt.js/issues/4839
- https://github.com/webpack/webpack/issues/8656
- https://github.com/npm/cli/pull/147
流れとしては、下記のような感じ
- Webpack v4.29 が依存している acorn というパッケージが更新された
- Nuxt.js v2.4 は Webpack v4.29 をに依存している
- npm のバグにより Webpack と acorn の依存をうまく解決できないのが問題らしいとのこと
この問題は Issue のリストに上げたように Nuxt.js 側でも報告されていて、yarn
でパッケージを取得している場合は発症しないことがわかっていました。
解決策
- 【解決策】acorn 6.0.5 以上をインストールする
公式の案内は下記のように acorn
を更新し、 npm dedupe
すると良いと案内がありましたが、こちらでは解決しませんでした。
rm -rf node_modules package-lock.json
npm install
npm update acorn --depth 20
npm dedupe
npm install している途中で、peerDependencies が欠けている警告が出ていたので試しに acorn を明示的にインストールすると問題は解決できました。
解決したあとで確認すると、同様の解決手法が Nuxt.js の Issue に追記されていました。
ref: https://github.com/nuxt/nuxt.js/issues/4839#issuecomment-458720610
その他対応したところ
PostCSS の設定が配列からオブジェクトが推奨に変更
v2.0 以降で対応の必要があります。
nuxt.config の build.postcss の設定が配列からオブジェクトに変更されており、オブジェクトで宣言するとデフォルトの設定といい感じにマージしてくれます。
一方で配列で定義すると Nuxt.js で設定されている cssnano などの仕組みが上書きされて消えてしまうので注意が必要です。
日本語版マニュアルは配列で設定する方法が乗っているのですが英語版ですと更新されているようでした
TypeScript の対応方法の追従
module/typescript.js などを用意して、旧来の手法でTypeScriptを使用していた場合は Nuxt.js が持っているTypeScript対応の仕組みと重複するので、必要に応じて削除や調整が必要です。
まとめ
「ねんがんの Nuxt.js v2.4 に なったぞ! ▼」
- ハマりポイントとしては以上のような依存関係のものが大きかったです。
- 対応策を探す上で、マニュアルやリリースノートを確認することが重要になってきますが、日本語翻訳に頼り切るのではなく、英語のIssueやPRなどの1次情報も目を通していくお気持ちが大切でした。