カタベログ

IT技術に関するブログを書きたい.食べ物関連はInstagramをご参照の事.

Next.jsにTerserを入れてる状態でAPI Routesを使う際に気をつけなければならない事

TL;DR

  • Terserのdrop_consoleを使わずにNext CompilerのremoveConsoleを使いましょう
    • そうしないとバックエンド側のconsole.logprocess.stdout.writeも消えます

環境

フロントエンドは移り変わりが早いので、ちゃんと各フレームワーク、ライブラリのバージョンを残しておきましょう。

{
    "next": "12.1.0",
    "terser-webpack-plugin": "^5.3.1"
}

気づき

開発している中で、開発環境ではNODE_ENVdevelopmentにして、ソースマップ出したりコンソールログを消さないようにしてデバッグしてました。開発も終盤、ステージング環境にデプロイして見て動作確認しようとNODE_ENVproductionにしてみました。フロントエンドは順調に動いてましたがデータ不備があってAPIから400エラーが返ってきました。ログを見て原因を突き止めようとしたところ、「あれれ〜?おかしいな〜ログが出てないぞ〜?」ってなりました。姉さん、事件です。*1

調査

NODE_ENVdevelopmentにすればログが出るのは確認できたので、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:筆者に姉はいません