😱

【Nuxt】server side pluginのグローバル変数の取り扱いに気づいたこと

2021/04/30に公開

nuxtのプラグインに関して

nuxtのプラグインはSSRでもCSRでも実行されます。プラグイン名をxxx.server.jsにするとSSRだけ実行され、xxx.client.jsにするとCSRだけ実行されます。
プラグインはとても便利ですが、SSRのプラグインでグローバル変数を取り扱う際に気をつけなければならないことがあります。

注意点

結論から言うと、production環境でのグローバル変数は全部のユーザーに共有されてしまう
実際にプラグインを入れて解説します。

コード

下記ファイルを作成します。

// /plugins/test.server.js
let magicState = false;
export default ({ route }) => {
  if (route.query.test) magicState = true;

  console.log(magicState);
};

nuxt.config.jsのpluginに下記を入れます。

plugins: ['~/plugins/test.server',]

これは、URLにtestというqueryがある場合、trueをコンソールに出力し、queryがない場合falseを出力するシンプルのテストです。

ではまずdevelopmentモードでテストして見ます。
下記コマンドでサーバー起動します。

npm run dev
もしくは
yarn dev

developmentモードのテスト結果

サーバー起動したらブラウザからアクセスして見るとターミナル上でfalseが出力されます。

次にURLに?test=1を入れてアクセスして、再度ターミナルの出力を見てみると

testがあるので、ここまでの結果は予想通りです。

では?test=1を削除して、再度アクセスしてみると

もちろんfalseが出力されますね。
ここまでのテストの結果は当たり前過ぎくらい予想通りです。
ではproductionモードで同じテストしてみましょう。
下記コマンドで切り替えます。

npm build
npm start
もしくは
yarn build
yarn start

productionモードのテスト結果

ここで同じ手順でテストしていきます。
まずはqueryを入れないでアクセスしてみる。

次にqueryを入れてアクセスします。

ここまで予想通りですね。
ではqueryを削除して再度アクセスすると。

!!?!?!!
query入れてないのにtrueになります。
これはproductionモードだけ起きる現象です。
もし例のグローバル変数はPC / スマホの表示に関するフラグ変数であれば、本番環境にリリースするとPCからのアクセスなのにスマホのレイアウトになったり、スマホではPCのレイアウトになったりという不具合が起きてしまいます。

結論

SSRでのプラグインにはグローバル変数を使わずに、関数の中に変数を入れること。
すでにそう実装している方はこれを機に一度担当してるプロジェクトにはこういうコードがあるか確認した方が良さそうです。

最後まで読んで頂き、ありがとうございました。
それではまた!

Discussion