Next.jsにTerserを入れてる状態でAPI Routesを使う際に気をつけなければならない事
TL;DR
- Terserの
drop_console
を使わずにNext CompilerのremoveConsoleを使いましょう- そうしないとバックエンド側の
console.log
もprocess.stdout.write
も消えます
- そうしないとバックエンド側の
環境
フロントエンドは移り変わりが早いので、ちゃんと各フレームワーク、ライブラリのバージョンを残しておきましょう。
{ "next": "12.1.0", "terser-webpack-plugin": "^5.3.1" }
気づき
開発している中で、開発環境ではNODE_ENV
をdevelopment
にして、ソースマップ出したりコンソールログを消さないようにしてデバッグしてました。開発も終盤、ステージング環境にデプロイして見て動作確認しようとNODE_ENV
をproduction
にしてみました。フロントエンドは順調に動いてましたがデータ不備があってAPIから400エラーが返ってきました。ログを見て原因を突き止めようとしたところ、「あれれ〜?おかしいな〜ログが出てないぞ〜?」ってなりました。姉さん、事件です。*1
調査
NODE_ENV
をdevelopment
にすればログが出るのは確認できたので、Terserのdrop_console
が悪さをしている事はすぐわかりました。てっきりフロントエンドだけ対象に消すのかと思ってましたが、API RoutesもWebPackでバンドルされる対象になるので、Terserのオプションの餌食になるようでした。とはいえ、console.log
以外に標準状態でログを出す方法なんてないと思っていたので途方に暮れてました。Next.jsのロギングについて調べていると公式サイトにヒントがありました。
お恥ずかしながら、process.stdout
という機能があるのを知らなかったのです。これで勝ったと思ってAPI関連コードのconsole.log
を全て書き換えて、調子に乗って環境変数に応じてログを出し分ける簡易のロガーモジュールまで作っちゃったりして、更に更にJestでユニットテストまで作って「完璧……。」と思ってサーバにデプロイしてみると……。
process.stdout
に変えても出てこないログ
出ないんですが、ログ?
実装ミスったかと思いましたが、でも、Babelで逃しているバッチのコーデは同じモジュール使ってもログが出ているので、作ったモジュールが悪い訳ではなさそう。フロントに余計なログは出したくないからdrop_console
を入れたい。でもそのせいでAPIでログ取れないのは致命的。フロントのログを全て抜くPR作るか悩んでいましたが、諦めきれず調べた結果、助けてくれましたね公式サイトが。公式サイト様様。
Next CompilerのremoveConsoleというオプションがTerserのdrop_console
と同じ機能を提供してくれていました。「API RoutesもNext.jsの機能なので、これならきっとフロントとバックエンドを区別して取り除いてくれるだろう!」そう思って設定ファイルを更新し、感謝のデプロイ!!1無事ログが出力されました。
*1:筆者に姉はいません