2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Nuxt3で一部のページを本番ビルドで丸ごと除外する備忘録

2
Last updated at Posted at 2024-03-14
  1. 勉強用だけどAWS(Lambda)にデプロイしているサーバーレスアプリケーションの中に新たにWebRTCを使ったクローズドなチャット機能を作った
  2. クローズドなチャットはインターネット上に公開してしまうと電気通信事業法に引っかかってしまうかもしれない
  3. 本番ビルドからチャットに関するページを除きたくなった
    • ブランチ切って避けたりはしたくない(存在を忘れそうなので)
    • ローカルの開発サーバーでのみ動作確認可能としたい
    • リバースエンジニアリングも不可能にしたい

という流れ。

2024/03/26追記
Nuxt3の公式ドキュメント読んだら.nuxtignoreというファイルを設定することでも実現できることがわかりました。
https://nuxt.com/docs/guide/directory-structure/nuxtignore

こちらを利用するのが正解かも?(ドキュメントに書いてあるので)

フォルダ構成とチャット画面について

関係しているもののみ抜粋。以下のような感じ

components/
  ┣ layouts/
  ┃ ┗ error/
  ┃   ┗ WebRTCProductionExcludeError.vue ← 本番環境でクローズドチャットのURLにアクセスしたときのエラー画面
  ┗ WebRTC-chat/ ← webrtc-chat.vueで使用するコンポーネントをまとめたディレクトリ
    ┣ publish/
    ┃ ┗ WarnMessage.vue ← 除外したくない
    ┣ ChatMessagesTimeline.vue ← 除外したい
    ┣ ClipboardCopy.vue ← 除外したい
    ┣ MessageEditor.vue ← 除外したい
    ┗ MessageView.vue ← 除外したい
pages/
  ┗ demo/
    ┗ appendix/
      ┗ webrtc-chat.vue ← 除外したい
types/
  ┗ webrtc-chat.d.ts
package.json
nuxt.config.ts

作成したチャット画面は以下のような形になっています。

image.png

修正内容について

  • Nuxt3においてビルドを担当しているのはViteの中のESBuildrollup
    • Nuxt3 ⇒ Vite ⇒ ESBuild,rollup という関係
  • 本番ビルドを行うときに使用されるrollupのオプションとして特定のページコンポーネントを外部から読み込むコンポーネントと定め、ビルドに含めないようにすれば良さそう
    • 具体的にはnuxt.config.tsのViteを使ったビルドオプション(vite.build.rollupOptions.external)の設定を環境変数を元にした分岐によってセットする/しないといった処理を書くことで解決できました
  • ※今回の件には関係ない気がしますがサーバーサイドレンダリングは無効化しているプロジェクトになります。
nuxt.config.ts
import { createResolver } from "@nuxt/kit";

const { resolve } = createResolver(import.meta.url);

// 除外したいページコンポーネントについてnuxt.config.tsからの相対パスの配列を作成
// createResolverから取り出したresolve関数で絶対パスに変換
// components以下のコンポーネントは使って無ければ自動で除外されるはず
const pagesToExcludeInProduction = [
  "pages/demo/appendix/webrtc-chat.vue",
].map((path) => resolve(path));

export default defineNuxtConfig({
  ssr: false,

  vite: {
    build: {
      rollupOptions: {
        external: process.env.NODE_ENV === "production" ? pagesToExcludeInProduction : undefined,
      },
    },
  },
});
  • NODE_ENV環境変数はnuxi devのときdevelopmentnuxi buildのときproductionを取り、今回のやりたいことに合致するので採用しました
  • NODE_ENV環境変数がproductionのとき除外対象となるページのVueファイルのパス配列が渡り、そうでないとき初期値のundefinedが渡ります

動作確認

① ローカルの開発サーバー上では特に問題なく動作することを確認

$ npx nuxt dev
Nuxt 3.10.3 with Nitro 2.9.1                                                                                           9:03:05 PM
                                                                                                                       9:03:05 PM
  ➜ Local:    http://localhost:3000/
  ➜ Network:  use --host to expose

ℹ Using yup with vee-validate                                                                                         9:03:07 PM
  ➜ DevTools: press Shift + Alt + D in the browser (v1.0.8)                                                            9:03:07 PM

ℹ Compiled plugins/server.mjs in 527.94ms                                                                             9:03:09 PM
ℹ Compiled plugins/client.mjs in 536.66ms                                                                             9:03:09 PM
ℹ Compiled types/plugins.d.ts in 592.84ms                                                                             9:03:09 PM
ℹ Start build:done hook.                                                                                              9:03:10 PM

~~~省略~~~

ℹ End build:done hook.                                                                                                9:03:11 PM
ℹ Vite client warmed up in 9691ms                                                                                     9:03:19 PM
✔ Nuxt Nitro server built in 3550 ms                                                                            nitro 9:03:22 PM
チャット画面
初期表示
image.png
ホスト⇒クライアントのキー渡してる画面
image.png
チャット①
image.png
チャット②
image.png

② node-server向けのプリセットで本番ビルドを実施&node-serverを起動しクローズドチャットのページにアクセスし404エラーとなることを確認

$ NITRO_PRESET=node-server npx nuxt build
Nuxt 3.10.3 with Nitro 2.9.1                                                                                           9:01:36 PM
ℹ Using yup with vee-validate                                                                                         9:01:37 PM
ℹ Building client...                                                                                                  9:01:39 PM
ℹ vite v5.1.4 building for production...                                                                              9:01:39 PM

~~~省略~~~

✔ You can preview this build using node .output/server/index.mjs                                                nitro 9:01:53 PM

$ node .output/server/index.mjs
Listening on http://[::]:3000

image.png

クローズドなチャットのURLにアクセス
↓
app.vueの表示処理が走る
↓
TypeError: error loading dynamically imported moduleのエラーが発生
↓
app.vueと同階層に配置したerror.vueの表示処理が走る
↓
error.vueの中でuseRouteコンポーザブルから取得できるルートのパスが`/demo/appendix/webrtc-chat`のとき特別なエラー画面を表示

という流れ(のはず:thinking:


③ AWS Lambda向けのプリセットで本番ビルドを実施&生成物(.outputディレクトリ以下のリソース)について除外したいページのテキストが検索で引っかからないことを確認

$ NITRO_PRESET=aws-lambda npx nuxt build
Nuxt 3.10.3 with Nitro 2.9.1                                                                                                10:31:50 PM
ℹ Using yup with vee-validate                                                                                              10:31:51 PM
ℹ Building client...                                                                                                       10:31:53 PM
ℹ vite v5.1.4 building for production...                                                                                   10:31:53 PM

~~~省略~~~

ℹ ✓ built in 1.05s                                                                                                         10:32:15 PM
✔ Server built in 1103ms                                                                                                   10:32:15 PM
ℹ Start build:done hook.                                                                                                   10:32:15 PM
ℹ copied PrimeVue themes from /app/node_modules/primevue/resources/themes to /app/public/themes                            10:32:15 PM
ℹ End build:done hook.                                                                                                     10:32:15 PM
✔ Generated public .output/public                                                                                    nitro 10:32:15 PM
ℹ Building Nuxt Nitro server (preset: aws-lambda)                                                                    nitro 10:32:16 PM
✔ Nuxt Nitro server built                                                                                            nitro 10:32:24 PM
  ├─ .output/server/chunks/_/articles.mjs (1.89 kB) (680 B gzip)
  ├─ .output/server/chunks/_/articles.mjs.map (1.38 kB) (496 B gzip)
~~~省略~~~
  ├─ .output/server/index.mjs (233 B) (175 B gzip)
  └─ .output/server/package.json (4.14 kB) (1.11 kB gzip)
Σ Total size: 5.22 MB (1.22 MB gzip)
.outputをエディタで開いた状態
image.png
.output/public/_nuxt以下にWebRTCチャット用のjsファイルが生成されていないことを確認
image.png
WebRTC chat内のテキストで検索(WebRTCを使ったP2Pチャットです)
ヒットしないことを確認
image.png
ソース側でWebRTCを使ったP2Pチャットですを検索したときの結果
ヒットすることを確認image.png

参考リンク

2024/03/26追記

記事の先頭に追記した.nuxtignoreについて自分のプロジェクトでも少し使ってみました。

  • 書き方は.gitignoreと一緒
  • pages/ディレクトリの他にlayouts/middleware/などのディレクトリのファイルも除外できるみたい

.nuxtignore設定

以下のようなファイルをプロジェクトのルートに作成

.nuxtignore
pages/demo/appendix/webrtc-chat.vue

動作確認1

まずは開発サーバーを起動して確認

$ npx nuxt dev

↓アプリケーション内のサイドバーに設置したNuxtLinkから除外対象のページに遷移しようとしたところ用意した固有のエラー画面ではなく404エラー画面が表示されました

image.png

  • この挙動はvite.build.rollupOptions.externalを利用してページを除外したときには見られなかった動作でした
    • error.vueの実装次第かもしれない

↓除外対象のページのURLに直アクセスしようとしてこの間作ったerror.vueを経由したエラー画面が表示できることを確認

image.png


↓その他、開発サーバー起動中に.nuxtignoreを編集すると保存時に再読み込みされることを確認

image.png

動作確認2

次にnode-server向けの本番ビルドを実施して確認

$ NITRO_PRESET=node-server npx nuxt build
$ node .output/server/index.mjs

開発サーバーを起動したときの動作確認と全く同一の動作となることを確認できました。

メモ

.nuxtignoreについて除外対象をGit管理しつつ「開発サーバーでは除外しない/本番ビルドでは除外する」を実現するのは以下のような自分の環境由来の問題もあり、やや手間な気がしました。

  • 切りのいいところでローカルの開発環境からServerless Frameworkを使用して手作業で本番デプロイしている
  • 本番ビルドで除外したいファイルについて.nuxtignoreで定義していると、開発サーバーを起動する際にも除外されてしまう

以下の内容は少し考えただけで試せていませんが、本番ビルドのデプロイ手順について以下のような形に作り替えることで開発サーバー/本番ビルドについて解決できそう

  1. 本番環境で除外したいページについて.nuxtignoreではなく.nuxtignore.productionみたいなファイルを用意
  2. GitHub Actionsのワークフローの中で本番ビルド(npx nuxt build)の前の手順としてcp .nuxtignore.production .nuxtignoreする
  3. Serverless Frameworkで本番ビルドの成果物一式をデプロイする
ワークフローのイメージ
$ cp .nuxtignore.production .nuxtignore
$ NITRO_PRESET=aws-lambda npx nuxt build
$ npx serverless deploy

追記の内容と直接関係ないけどServerless FrameworkについてGitHub Actionsのワークフローから利用する場合、以下のアクションを利用するのが良さそう?

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?