Node.js ExpressのテンプレートエンジンでFailed to lookup viewエラーになった時はどうすればいいか?
はじめに
こんにちは、SHIFT の開発部門に所属しているKatayamaです。
Node.js の Express にはテンプレートエンジンと呼ばれるものがあります。これは static な(静的な)テンプレートファイルを基に、そのファイル内の変数などを置き換えて HTML ファイルを作成してクライアント(ブラウザ)に返す機能です。
今回は、このテンプレートエンジンを利用している時に、"Failed to lookup view "./index.ejs" in views directory "/root/workspace/post-restaurant-reviews/views"" というような、views のエラー(ビューディレクトリ内のビューの検索失敗)が出た時の対処方法についてみていきたいと思います。
Failed to lookup view エラーになった時はどうすればいいか?
エラーの内容と元々の実装
エラーが発生する時の実装としてはこのようなコード。
// ./src/app.js
// ※ES Modulesを利用しているが、ES Modulesを利用しない場合は、"const express = require('express');"のように実装すればいい
import express from "express";
import router from "./routes/index";
const port = process.env.PORT;
const app = express();
app.set("view engine", "ejs");
app.use("/", router);
app.listen(port, () => {
console.log(`Application listening at ${port}`);
});
// ./src/routes/index.js
// ※こちらも同様にES Modulesを利用している
import { Router } from "express";
const router = Router();
router.get("/", (req, res) => {
res.render("./index.ejs");
});
export default router;
この時のエラーとしては以下。
Error: Failed to lookup view "./index.ejs" in views directory "/root/workspace/post-restaurant-reviews/views"
at Function.render (/root/workspace/post-restaurant-reviews/node_modules/express/lib/application.js:580:17)
at ServerResponse.render (/root/workspace/post-restaurant-reviews/node_modules/express/lib/response.js:1017:7)
at /root/workspace/post-restaurant-reviews/dist/app.js:20:7
at Layer.handle [as handle_request] (/root/workspace/post-restaurant-reviews/node_modules/express/lib/router/layer.js:95:5)
at next (/root/workspace/post-restaurant-reviews/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/root/workspace/post-restaurant-reviews/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/root/workspace/post-restaurant-reviews/node_modules/express/lib/router/layer.js:95:5)
at /root/workspace/post-restaurant-reviews/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/root/workspace/post-restaurant-reviews/node_modules/express/lib/router/index.js:341:12)
at next (/root/workspace/post-restaurant-reviews/node_modules/express/lib/router/index.js:275:10)
※ディレクトリ構成は以下(一部省略している)。
[root@localhost ...]# tree -I "node_modules|.git"
.
├── babel.config.js
├── package.json
├── src
│ ├── app.js
│ ├── routes
│ │ └── index.js
│ └── views
│ └── index.ejs
├── webpack.config.js
└── yarn.lock
※ES Modules を利用した実装のための設定については、Node.js で import・export(ES6 の構文)を使えるように webpack × Babel の設定をやってみたを参照。
対処方法
公式に、
と書かれている通り、デフォルトでは views のディレクトリはそのアプリケーションのルートディレクトリになるので、./views 以下に view があるものとして動く。
この views ディレクトリを変えればいいので、以下のように追加で実装をする。
// ES Modulesを利用するパターン
import appRoot from "app-root-path";
// 省略
app.set("view engine", "ejs");
app.set("views", appRoot.resolve("src/views"));
app.use("/", router);
// 省略
"app.set('views', appRoot.resolve('src/views'));" の部分で、アプリケーションのルートディレクトリにある src/views 以下(./src/views)を views ディレクトリに設定することができ、これによりエラーが発生しなくなる。
※app-root-pathは、相対パスから解放してくれるライブラリで、相対パスで書くのではなく、アプリケーションのどこからでもそのルートディレクトリのパスにアクセスできるようにする機能がある。今回は、「ルートディレクトリのパス+ src/views」というパスを作るのにこれを利用している。
・参考:Using template engines with Express
まとめとして
今回はテンプレートエンジンを利用する際に、views ディレクトリがデフォルトのルートディレクトリの直下にない時に発生するエラーの対処方法についてみてきた。自分でディレクトリの構成をカスタマイズしたい時などにはこうした設定が必要になるので忘れないようにしたい。
__________________________________
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/