Help us understand the problem. What is going on with this article?

Nuxt.js 2.4 に更新するためにやったこと

More than 1 year has passed since last update.

Nuxt.js 2.4 で変わったこと

公式リリースノートより一部抜粋していきます。
(※スクリーンショットはそれぞれ公式より引用させていただいております。)

image.png
ref: https://github.com/nuxt/nuxt.js/releases/tag/v2.4.0

TypeScriptに対応

  • やったね!! 公式に TypeScript サポートが開始されました
  • 内部的には ts-loaderfork-ts-checker-webpack-plugin が使用されています
  • :warning: Nuxt.js 内部の Webpack は js から優先的に依存を解決しようとするので同名の js と ts が存在する場合は注意
    • 必要な場合は module か config で extendBuild の仕組みを使用して Webpack に設定されている定義順を入れ替えましょう

image

prefetch に対応

ref: https://nuxtjs.org/api/components-nuxt-link

  • nuxt-link を使用している場合、dev.to みたいにページの先読みがされるようになりました。
  • 実装は google/quicklink.js を参考にしたそうです。
  • 意図的に prefetch を無効化するときは nuxt-link に no-prefetch を設定しましょう。

image

Store が HMR に対応

  • Hot Module Replacement に Vuex が対応し、ストアのコードをいじっても初期化されなくなりました

image

Vetur サポートの強化

  • VSCode で Vetur を使用している場合、Nuxt オリジナルの関数やメンバーが補完されるようになりました

image

生成される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

エラーの例

Nuxt.js が出力するファイルで構文エラーが起こった例
image.png

今まで使用できていた画像を参照できなくなった例
image.png

大量に起こった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 の更新で直るかもしれない(?)

image.png

解決策

  • 【解決策】必要に応じて<no-ssr>を使いましょう
  • DOMの不整合が起きている箇所のうち、差分検知ができている場合は、開発モードの場合のみヒントになる情報が検証ツールで出ています。
  • CSSのセレクタやDOMの構造を頼りに問題箇所を特定して根本的に直すか、工数的に難しい場合などは<no-ssr>を活用しましょう。

.nuxt/router.js の Unexpected token error

原因

これが一番困った...
下記のIssueをにたどり着きどうやら npm のバグによるものらしく、パッケージの依存解決に失敗する場合がある様子。

流れとしては、下記のような感じ

  • 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 すると良いと案内がありましたが、こちらでは解決しませんでした。

image.png

rm -rf node_modules package-lock.json
npm install
npm update acorn --depth 20
npm dedupe

npm install している途中で、peerDependencies が欠けている警告が出ていたので試しに acorn を明示的にインストールすると問題は解決できました。

image.png

解決したあとで確認すると、同様の解決手法が Nuxt.js の Issue に追記されていました。

ref: https://github.com/nuxt/nuxt.js/issues/4839#issuecomment-458720610


その他対応したところ

PostCSS の設定が配列からオブジェクトが推奨に変更

v2.0 以降で対応の必要があります。

nuxt.config の build.postcss の設定が配列からオブジェクトに変更されており、オブジェクトで宣言するとデフォルトの設定といい感じにマージしてくれます。
一方で配列で定義すると Nuxt.js で設定されている cssnano などの仕組みが上書きされて消えてしまうので注意が必要です。

日本語版マニュアルは配列で設定する方法が乗っているのですが英語版ですと更新されているようでした

image.png

TypeScript の対応方法の追従

module/typescript.js などを用意して、旧来の手法でTypeScriptを使用していた場合は Nuxt.js が持っているTypeScript対応の仕組みと重複するので、必要に応じて削除や調整が必要です。


まとめ

:tada: 「ねんがんの Nuxt.js v2.4 に なったぞ! ▼」

  • ハマりポイントとしては以上のような依存関係のものが大きかったです。
  • 対応策を探す上で、マニュアルやリリースノートを確認することが重要になってきますが、日本語翻訳に頼り切るのではなく、英語のIssueやPRなどの1次情報も目を通していくお気持ちが大切でした。
dojineko
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした