Aikの技術日記

技術的な進捗とか成果とかを細々と投稿するブログです。時々雑記も。

Nuxt.js使ってみた Part1~Nuxt.js概要まとめ編~

はじめに

お久しぶりです、筆者です。

最近、お仕事でNuxt.jsやVue.jsに触れる機会が多くなってきています。
これまでC#を中心にサーバーサイド側を携わってきましたが…。
ようやくフロントエンド系に携われるなと小躍りしている最中です。

せっかくなので、これらの知識について色々とまとめていこうかと。
当分はNuxt.jsを中心に見ていくことになるかな…。
((筆者がNuxt.jsから入っちゃったので、「それVue.jsだよ」という所もいっぱいありそうですが。

それでは行きましょう。

Nuxt.jsとは?

まずはNuxt.jsとはなんなのか、から。

Nuxt.jsを一言で言うと、「Vue.jsのフロントエンド開発を楽にするフレームワーク」です。
というのも、Nuxt.jsには下記のパッケージが含まれており:

  • Vue2
  • Vue-Router
  • Vuex
  • Vue Server Render(SPAモード時は異なる)
  • Vue-Meta

更に、create-nuxt-appを用いたNuxt.jsの初期構築を済ませた時点で、各パッケージを使用したいい感じのフォルダ構造&機構も生成してくれます。

例えば、Vue-Routerを使用したルーティング機構が備わっている&指定されたフォルダ(pages)にファイル追加するだけで自動ルーティングを行ってくれたり…。
例えば、componentを置く場所であるcomponentsフォルダや、Webページのレイアウト情報を配置するlayoutsフォルダ、Vuexの処理を記述するファイルを配置するstoresフォルダを作ってくれたり…。

「どのファイルをどこに配置するか」がNuxt.js側で提供されるので、Nuxt.jsどころかVue.jsにそこまで詳しくなくても「やりたいこと」に集中して開発が進められるのが素敵ポイントです。

更にさらに、create-nuxt-appを用いて初期構築を行う時点で、webpackやBabel等の環境を自動構築してくれるのも嬉しいポイント。
npx create-nuxt-app [プロジェクト名](かyarn create nuxt-app [プロジェクト名])を実際に叩いてみると、

  • JavaScriptにする? TypeScriptにする?
  • npmで管理する? それともyarn?
  • 使用するサーバーサイドのフレームワークは?
    • ExpressやKoaなどの8種から選べます
  • 使用するUIフレームワークは?
    • BootstrapやVuetifyなどの11種から選べます
  • 使用するテスティングフレームワークは?
    • JestやAVAなどの3種から選べます、利用しないと言う選択肢もあります
  • SSRにする? SPAにする?
  • 下記の中からNuxt.jsのモジュールで必要なのある?(使用しない事ももちろん可)
    • axios
    • PWA Support(Webの技術を使いモバイルアプリケーションのように振舞う)
    • Content
  • 下記の中から使用するLinter選んでちょ(使用しない事ももちろん可)
    • ESLint
    • Prettier
    • Lint staged files
    • StyleLint

…と、様々なことを聞いてくれ、選択に応じてそのパッケージやフレームワークを自動インストールしてくれます。

筆者もそうですが、「○○作りたいんだ〜〜!」みたいに明確に作りたいものがあってからWebアプリを作るタイプの人だと、技術選定って正直面倒だったりやる気が削がれる要素の1つになりやすいので…。
こうしてある程度の選択肢を与えつつ、簡単に環境構築ができるってだけでもすごくありがたいなぁと思います。

また、これだけのパッケージを同梱していながら割と軽量というのも素敵ポイントです。
webpack, vue-loader, babel-loaderを用いてbundle化やminify化を行えば、全てのパッケージを60KB程の容量に圧縮可能とのこと。
※ソース: Nuxt ライフサイクル - NuxtJS

ちなみに…このNuxt.js、日本のコミュニティもかなり活発に動いているっぽいです。
何かしらにハマったとしても、既に先人が似たようなハマりをして&ブログ等の記事にまとめて下さってるのが散見されます。
根幹はVue.jsですし、Vue.jsの日本コミュニティも活発である事も相まってたくさんの記事がヒットしてくれます。

余程変わったことをしない限り、ググって解決出来るって感じですね。素晴らしい…。
((これがマイナーな技術だと、ググっても解決できないのでね…(経験談)

余談

筆者の意見ですが、多分Nuxt.jsができた理由は…。
昨今のフロントエンド技術の進化に伴いVue.jsでの開発が浸透していく中、Vue.jsを用いたWebアプリの開発スタイルが段々と固定化されていく様になり…。
「Vue.jsを用いて開発するならこれとこれとこれが必要だよね〜」というスタンダードなモデルが確立されていきました。

そんな中で登場したのがNuxt.jsなんじゃないかなぁと。
その証拠に、Nuxt.js内にはVue.js開発においてスタンダードなモデルを構築するパッケージがたくさん入っていますしね。

ちょっと長くなりましたが、概要はこの辺りで。
次からはNuxt.jsについて調べて行った中で、きになるポイントや面白ポイントを小ネタ形式で出していこうかなと。

Nuxt.js小ネタ集

※小ネタ集なので、コンテンツ毎の一貫性はなく様々なことについて書いています。ご了承をば…。

SSRとSPAの切り替えについて

Nuxt.jsの特徴として、サーバーサイドレンダリング(Universal SSRモード)とクライアントサイドレンダリング(SPAモード)を切り替え可能です。
ちなみにその切り替えは、実行時やビルド時にパラメータ値を設定するだけで可能です。お手軽!

  • ローカル実行時:
    • SSR: nuxt
    • SPA: nuxt --spa
    • 静的:
  • ビルド時:

参考記事 - Nuxt.js公式Docs

静的ファイルの生成も可能

Nuxt.jsを使用して作成したアプリを、静的HTMLドキュメントとして生成することも可能です。
ルートディレクトリからnpm run generateコマンドを叩くことで生成可能です。

例えば、以下のファイル構成だった場合:

-| pages/
----| about.vue
----| index.vue

次のファイルが生成されるイメージです:

-| dist/
----| about/
------| index.html
----| index.html

Nuxt.js内でのSCSSファイルの使い方

Nuxt.js…というかVue.jsの考え方ですが、Componentに関係するCSSJavaScriptはそのComponentの中に記述するという考え方があります。
このため、スタイルシートを書く際は基本Component内に書く…とは思いますが…。
中にはそうも言えない事情もあるかなと思います。
((1万行もある既存CSSを移行したりね…

そんな中で、特にSCSSを使用するにはどうするかをまとめてみました。
create-nuxt-appを用い、初期構築を終わらせている前提です

①まず、SCSSに必要なモジュールをインストールします。

# by npm
> npm install sass-loader node-sass --save-dev

# by yarn
> yarn add npm install sass-loader node-sass

②次に、.scssファイルを作成しましょう。
プロジェクト内のassetsフォルダにsassフォルダを作成。
sassフォルダ内にSCSSファイルを作成。

③最後に、nuxt.config.jsの設定
cssの部分に、下記の様に追加設定。これで完了です!

  /*
   ** Global CSS
   */
  css: [
    { src: '~/assets/sass/app.scss', lang: 'scss' },
  ],

参考記事: suzu6.net

Nuxt.jsをBFF(Backends For Frontends)にする

Nuxt.jsの本来の使い方とは確実に離れますが…。
Nuxt.jsで構築したWebアプリをBFF化する事もギリギリ可能…かもしれません。

※ちなみにBFF(Backends For Frontends)とは、フロントエンドのためのバックエンド(サーバー)、フロントエンドのためにAPIをコールしたり、HTMLを生成したりするサーバーのことを指します。
参考記事: BFF(Backends For Frontends)超入門――Netflix、Twitter、リクルートテクノロジーズが採用する理由 (1/2):マイクロサービス/API時代のフロントエンド開発(1) - @IT

肝となるのはNuxt.jsの機構に存在する「serverMiddleware」というもの。
これを使用すると、Nuxt.js内部でAPIを構築可能です。
※詳細にいうと、vue-server-renderer の前にサーバー側で実行される処理となります。

一般的には「APIリクエストの処理」や「アセットの処理」などのサーバー固有のタスクとして使用する様ですが…。

ちなみに、Nuxt.js内部でNuxt.js内部に構築されたAPIを使用する場合、本番運用時には特別な設定が必要なのでご注意を。
※参考: Nuxt.js+TypescriptでのserverMiddlewareの利用について(もう少し補足) - Qiita

ディレクトリが持つ役割について

create-nuxt-appを用い、初期構築を終わらせている前提で…。
assetsディレクトリとmiddlewareディレクトリが持つ意味について調べてみました。
※他ディレクトリを調べる気力は持ちませんでした…。

assetsディレクト
  • imgファイルやcssファイルなどのコンパイルされない静的ファイル置き場
  • /assets/img/[画像]/assets/sass/[sass,scssファイル]といった形で配置
  • 使用時は~/assets/img/img.jpgのように使用する

  • 配置されたファイルの全てに対し、JavaScriptファイル以外のファイルについては、file-loaderurl-loaderを用いて処理が行われる

    • デフォルトでは、1KB未満のファイルの場合Base64データURLとしてインライン化されたコンテンツとなる。
    • 1KB以上の画像やフォントファイルについては、.nuxtディレクトリ下にファイルごとコピーされる
<!-- pages/index.vueに下記の様に展開されていたとしたら -->
<template>
  <img src="~/assets/image.png">
</template><!-- 1KB以上のファイルに対しては、下記の様に展開される -->
<img src="/_nuxt/img/image.0c61159.png">
  • staticフォルダも静的ファイルの配置場所である

    • こちらに配置されたファイルはfile-loaderurl-loaderを用いた処理が行われない
    • 例えば/static/favicon.icoと配置した際は、localhost:3000/favicon.icoとして使用可能
  • 参考: assetフォルダの解説 - Nuxt.js Docs

middlewareディレクト

テスティングフレームワークについて

create-nuxt-appで選択できるテスティングフレームワークの中で、よく使われている…らしい2種を少しだけ調べてみました。

Nuxt.jsで使用するHTMLテンプレートのカスタマイズ

create-nuxt-appで構築したWebアプリでは、<head>タグなどの部分をカスタムできるファイルは存在しませんが…。
プロジェクトのルートフォルダ上にapp.htmlファイルを作成すれば、カスタム可能です。
((app.htmlファイルがNuxt.jsで使用されるHTMLテンプレートとなります

なお、デフォルトテンプレートは下記の様なHTMLとなっているそうです:

<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
    {{ APP }}
  </body>
</html>

カスタムする際は、以下の様に{{ HTML_ATTRS }}といった文字列を消さない様に作成しなければならない様です:

<!DOCTYPE html>
<!--[if IE 9]><html lang="en-US" class="lt-ie9 ie9" {{ HTML_ATTRS }}><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><html {{ HTML_ATTRS }}><!--<![endif]-->
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
    {{ APP }}
  </body>
</html>

おわりに

今回の記事では、Nuxt.jsについての概要だったりなんだったりを記してみました。
((まだ使用してみてはないので…よく考えたらタイトル詐欺でしたね…

次回Partではいよいよ実践編として、チュートリアル系記事を参考にTODOアプリを作って行った中での使用感とかを述べていければと。
それでは|д゚*)