Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EJS] Error: Failed to lookup view "home-guest" in views directory "views" #34

Open
henry1491491 opened this issue Oct 28, 2019 · 29 comments

Comments

@henry1491491
Copy link

henry1491491 commented Oct 28, 2019

感謝使用 Node.js Taiwan AMA,以下附上簡單提問範例供參考,請把內容改成你自己遇到的問題

目的

目前學習的線上課程在做一個結合 Express + ejs 的網站,在設定 ejs 的時候跳出錯誤訊息

使用的工具

目前開發環境:

  • 作業系統: macOS Catalina 版本 10.15
  • Node 版本:v10.16.0
  • Express:6.12.0
  • EJS:6.12.0

專案連結

連結

操作流程

這是我的詳細步驟
及我的目錄如下

截圖 2019-10-28 下午6 47 24

遇到的問題

打開 localhost:3000 顯示

Error: Failed to lookup view "home-guest" in views directory "views"
    at Function.render (/Users/henry/Desktop/complex_app/node_modules/express/lib/application.js:580:17)
    at ServerResponse.render (/Users/henry/Desktop/complex_app/node_modules/express/lib/response.js:1012:7)
    at /Users/henry/Desktop/complex_app/app.js:10:7
    at Layer.handle [as handle_request] (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/layer.js:95:5)
    at /Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:275:10)

嘗試過的解法

我上 stack overflow 找了許多類似問題的解決方式,比如:

  • app.set('views', 'views') 改成 app.set('views', './views')
  • res.render('home-guest') 改成 res.render('home-guest.ejs')
    也試著改成
const express = require("express")
const path = require("path")
const app = express()

app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'ejs')

app.get('/', function (req, res) {
  res.render('home-guest')
})

app.listen(3000)

但卻跳出一樣的結果。
也有想過是否因為 home-quest.ejs 這隻檔案裡面都是 HTML,沒有任何 <% %> ejs 的東西

程式碼

以下是照著教學影片做到設定 EJS 樣板引擎這邊的完整程式碼(沒有自己更動過),然後就跳出錯誤

const express = require("express")
const app = express()

app.set('views', 'views')
app.set('view engine', 'ejs')

app.get('/', function (req, res) {
  res.render('home-guest')
})

app.listen(3000)

找了老半天,卻不知道問題出在哪裡,在此尋求各位幫助,十分感激!

@yckao
Copy link

yckao commented Oct 28, 2019

可以檢查一下 views 的權限
以及啟動的時候可以用
DEBUG=express:* node app.js
看一下 debug message

是說 express 有 6 OAO?
stable 不是 4 而已?

@henry1491491
Copy link
Author

可以檢查一下 views 的權限
以及啟動的時候可以用
DEBUG=express:* node app.js
看一下 debug message

是說 express 有 6 OAO?
stable 不是 4 而已?

感謝!還在研究你這段

express:application set "x-powered-by" to true +0ms
  express:application set "etag" to 'weak' +4ms
  express:application set "etag fn" to [Function: generateETag] +1ms
  express:application set "env" to 'development' +2ms
  express:application set "query parser" to 'extended' +0ms
  express:application set "query parser fn" to [Function: parseExtendedQueryString] +0ms
  express:application set "subdomain offset" to 2 +0ms
  express:application set "trust proxy" to false +1ms
  express:application set "trust proxy fn" to [Function: trustNone] +0ms
  express:application booting in development mode +1ms
  express:application set "view" to [Function: View] +0ms
  express:application set "views" to '/Users/henry/Desktop/complex_app/views' +0ms
  express:application set "jsonp callback name" to 'callback' +16ms
  express:router use '/' query +2ms
  express:router:layer new '/' +0ms
  express:router use '/' expressInit +2ms
  express:router:layer new '/' +0ms
  express:router use '/' serveStatic +1ms
  express:router:layer new '/' +0ms
  express:application set "views" to 'views' +0ms
  express:application set "view engine" to 'ejs' +0ms
  express:router:route new '/' +1ms
  express:router:layer new '/' +0ms
  express:router:route get '/' +0ms
  express:router:layer new '/' +0ms

我terminal 輸入 npm -v express,結果顯示 6 誒?
截圖 2019-10-28 下午7 27 10

@yckao
Copy link

yckao commented Oct 28, 2019

我terminal 輸入 npm -v express,結果顯示 6 誒?
截圖 2019-10-28 下午7 27 10

那是 NPM 的版本號
你要看是 package.json 裡面下的版本號

--

更正一下 npm ls 也可以

@yckao
Copy link

yckao commented Oct 28, 2019

express:application set "x-powered-by" to true +0ms
  express:application set "etag" to 'weak' +4ms
  express:application set "etag fn" to [Function: generateETag] +1ms
  express:application set "env" to 'development' +2ms
  express:application set "query parser" to 'extended' +0ms
  express:application set "query parser fn" to [Function: parseExtendedQueryString] +0ms
  express:application set "subdomain offset" to 2 +0ms
  express:application set "trust proxy" to false +1ms
  express:application set "trust proxy fn" to [Function: trustNone] +0ms
  express:application booting in development mode +1ms
  express:application set "view" to [Function: View] +0ms
  express:application set "views" to '/Users/henry/Desktop/complex_app/views' +0ms
  express:application set "jsonp callback name" to 'callback' +16ms
  express:router use '/' query +2ms
  express:router:layer new '/' +0ms
  express:router use '/' expressInit +2ms
  express:router:layer new '/' +0ms
  express:router use '/' serveStatic +1ms
  express:router:layer new '/' +0ms
  express:application set "views" to 'views' +0ms
  express:application set "view engine" to 'ejs' +0ms
  express:router:route new '/' +1ms
  express:router:layer new '/' +0ms
  express:router:route get '/' +0ms
  express:router:layer new '/' +0ms

是不是沒擷取完整(?
Error 的部分不見了 @@

@henry1491491
Copy link
Author

我terminal 輸入 npm -v express,結果顯示 6 誒?
截圖 2019-10-28 下午7 27 10

那是 NPM 的版本號
你要看是 package.json 裡面下的版本號

原來如此,怪不得 -v 後面輸入其他 module 結果都是 6 的版本 XD

@henry1491491
Copy link
Author

express:application set "x-powered-by" to true +0ms
  express:application set "etag" to 'weak' +4ms
  express:application set "etag fn" to [Function: generateETag] +1ms
  express:application set "env" to 'development' +2ms
  express:application set "query parser" to 'extended' +0ms
  express:application set "query parser fn" to [Function: parseExtendedQueryString] +0ms
  express:application set "subdomain offset" to 2 +0ms
  express:application set "trust proxy" to false +1ms
  express:application set "trust proxy fn" to [Function: trustNone] +0ms
  express:application booting in development mode +1ms
  express:application set "view" to [Function: View] +0ms
  express:application set "views" to '/Users/henry/Desktop/complex_app/views' +0ms
  express:application set "jsonp callback name" to 'callback' +16ms
  express:router use '/' query +2ms
  express:router:layer new '/' +0ms
  express:router use '/' expressInit +2ms
  express:router:layer new '/' +0ms
  express:router use '/' serveStatic +1ms
  express:router:layer new '/' +0ms
  express:application set "views" to 'views' +0ms
  express:application set "view engine" to 'ejs' +0ms
  express:router:route new '/' +1ms
  express:router:layer new '/' +0ms
  express:router:route get '/' +0ms
  express:router:layer new '/' +0ms

是不是沒擷取完整(?
Error 的部分不見了 @@

請問是這個嗎?
我後來再次輸入一次,結果顯示這樣
截圖 2019-10-28 下午7 58 00

@yckao
Copy link

yckao commented Oct 28, 2019

express:application set "x-powered-by" to true +0ms
  express:application set "etag" to 'weak' +4ms
  express:application set "etag fn" to [Function: generateETag] +1ms
  express:application set "env" to 'development' +2ms
  express:application set "query parser" to 'extended' +0ms
  express:application set "query parser fn" to [Function: parseExtendedQueryString] +0ms
  express:application set "subdomain offset" to 2 +0ms
  express:application set "trust proxy" to false +1ms
  express:application set "trust proxy fn" to [Function: trustNone] +0ms
  express:application booting in development mode +1ms
  express:application set "view" to [Function: View] +0ms
  express:application set "views" to '/Users/henry/Desktop/complex_app/views' +0ms
  express:application set "jsonp callback name" to 'callback' +16ms
  express:router use '/' query +2ms
  express:router:layer new '/' +0ms
  express:router use '/' expressInit +2ms
  express:router:layer new '/' +0ms
  express:router use '/' serveStatic +1ms
  express:router:layer new '/' +0ms
  express:application set "views" to 'views' +0ms
  express:application set "view engine" to 'ejs' +0ms
  express:router:route new '/' +1ms
  express:router:layer new '/' +0ms
  express:router:route get '/' +0ms
  express:router:layer new '/' +0ms

是不是沒擷取完整(?
Error 的部分不見了 @@

請問是這個嗎?
我後來再次輸入一次,結果顯示這樣
截圖 2019-10-28 下午7 58 00

路徑啊!看一下 Error message
你跑到 views 裡面了啦 QAQ

@henry1491491
Copy link
Author

express:application set "x-powered-by" to true +0ms
  express:application set "etag" to 'weak' +4ms
  express:application set "etag fn" to [Function: generateETag] +1ms
  express:application set "env" to 'development' +2ms
  express:application set "query parser" to 'extended' +0ms
  express:application set "query parser fn" to [Function: parseExtendedQueryString] +0ms
  express:application set "subdomain offset" to 2 +0ms
  express:application set "trust proxy" to false +1ms
  express:application set "trust proxy fn" to [Function: trustNone] +0ms
  express:application booting in development mode +1ms
  express:application set "view" to [Function: View] +0ms
  express:application set "views" to '/Users/henry/Desktop/complex_app/views' +0ms
  express:application set "jsonp callback name" to 'callback' +16ms
  express:router use '/' query +2ms
  express:router:layer new '/' +0ms
  express:router use '/' expressInit +2ms
  express:router:layer new '/' +0ms
  express:router use '/' serveStatic +1ms
  express:router:layer new '/' +0ms
  express:application set "views" to 'views' +0ms
  express:application set "view engine" to 'ejs' +0ms
  express:router:route new '/' +1ms
  express:router:layer new '/' +0ms
  express:router:route get '/' +0ms
  express:router:layer new '/' +0ms

是不是沒擷取完整(?
Error 的部分不見了 @@

請問是這個嗎?
我後來再次輸入一次,結果顯示這樣
截圖 2019-10-28 下午7 58 00

路徑啊!看一下 Error message
你跑到 views 裡面了啦 QAQ

不好意思⋯⋯
不過我在 complex_app 這邊執行這個 debug 命令還是沒有跑出你說的 error 部分誒
還是執行的時機或是目錄又錯了@@

截圖 2019-10-28 下午8 03 09

@yckao
Copy link

yckao commented Oct 28, 2019

不好意思⋯⋯
不過我在 complex_app 這邊執行這個 debug 命令還是沒有跑出你說的 error 部分誒
還是執行的時機或是目錄又錯了@@

截圖 2019-10-28 下午8 03 09

你跑起來有去 localhost:3000 嗎?

@henry1491491
Copy link
Author

不好意思⋯⋯
不過我在 complex_app 這邊執行這個 debug 命令還是沒有跑出你說的 error 部分誒
還是執行的時機或是目錄又錯了@@
截圖 2019-10-28 下午8 03 09

你跑起來有去 localhost:3000 嗎?

一樣是這段!

Error: Failed to lookup view "home_guest" in views directory "views"
    at Function.render (/Users/henry/Desktop/complex_app/node_modules/express/lib/application.js:580:17)
    at ServerResponse.render (/Users/henry/Desktop/complex_app/node_modules/express/lib/response.js:1012:7)
    at /Users/henry/Desktop/complex_app/app.js:8:7
    at Layer.handle [as handle_request] (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/layer.js:95:5)
    at /Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:275:10)

@yckao
Copy link

yckao commented Oct 28, 2019

一樣是這段!

Error: Failed to lookup view "home_guest" in views directory "views"
    at Function.render (/Users/henry/Desktop/complex_app/node_modules/express/lib/application.js:580:17)
    at ServerResponse.render (/Users/henry/Desktop/complex_app/node_modules/express/lib/response.js:1012:7)
    at /Users/henry/Desktop/complex_app/app.js:8:7
    at Layer.handle [as handle_request] (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/layer.js:95:5)
    at /Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:275:10)

用 DEBUG 開,然後...
開 localhost:3000
然後把 terminal 裡面的東西完整的貼上來...

@henry1491491
Copy link
Author

一樣是這段!

Error: Failed to lookup view "home_guest" in views directory "views"
    at Function.render (/Users/henry/Desktop/complex_app/node_modules/express/lib/application.js:580:17)
    at ServerResponse.render (/Users/henry/Desktop/complex_app/node_modules/express/lib/response.js:1012:7)
    at /Users/henry/Desktop/complex_app/app.js:8:7
    at Layer.handle [as handle_request] (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/layer.js:95:5)
    at /Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/henry/Desktop/complex_app/node_modules/express/lib/router/index.js:275:10)

用 DEBUG 開,然後...
開 localhost:3000
然後把 terminal 裡面的東西完整的貼上來...

是的,我照你的方式做了

  • 先執行 DEBUG=express:* node app.js
  • 然後到 localhost:3000
  • 然後 terminal 接著跳出以下訊息

截圖 2019-10-28 下午8 12 53
截圖 2019-10-28 下午8 13 03

@yckao
Copy link

yckao commented Oct 28, 2019

截圖 2019-10-28 下午8 13 03
要這個訊息的重點在於

express:view lookup
express:view stat
express:view stat

這樣原因就很清楚
/Users/henry/Desktop/complex_app/views/home_guest.ejs
這部分沒有被判斷為一個檔案
(我就是在等這段,要想解決問題,要先知道問題的原因)

你可以在 node 的 REPL 裡面試試看這一段

const fs = require('fs')
fs.statSync('/Users/henry/Desktop/complex_app/views/home_guest.ejs').isFile()

這邊參考到的是
express/lib/views #L174

function tryStat(path) {
  debug('stat "%s"', path);

  try {
    return fs.statSync(path);
  } catch (e) {
    return undefined;
  }
}

@henry1491491
Copy link
Author

view stat

感謝你的回覆!
我統整一下不知道是否有理解錯誤。

因為看到 express:view stat 這兩段,表示 home_guest.ejs 這個檔案錯誤
這時就要載入 fs 模組( node 的檔案管理系統)然後 terminal 先輸入 node 進入 repl 模式?
然後輸入以下內容查看結果是不是一個檔案(用 .isFile() 這個方法)

fs.statSync('/Users/henry/Desktop/complex_app/views/home_guest.ejs').isFile()

然後跳出:
截圖 2019-10-28 下午8 43 56

@yckao
Copy link

yckao commented Oct 28, 2019

其實整個的思路是這樣
我一開始是在看錯誤從哪邊拋出
從錯誤訊息找會找到
lib/application.js #L580

稍微往上找一下會進這邊的條件是 #L576 的 if (!view.path)
所以就要去看 View 是怎麼操作的
會追到 lib/view.js #L52

稍微往下翻一點點會看到他在做 lookup (翻譯起來算尋找(? 不知道怎麼翻好)
要滿足 path 是 falsy 的值代表 this.resolve(dir, file) 沒東西
也就是 this.resolve(dir, file); 沒東西

繼續往下看就會看到

View.prototype.resolve = function resolve(dir, file) {
  var ext = this.ext;

  // <path>.<ext>
  var path = join(dir, file);
  var stat = tryStat(path);

  if (stat && stat.isFile()) {
    return path;
  }

  // <path>/index.<ext>
  path = join(dir, basename(file, ext), 'index' + ext);
  stat = tryStat(path);

  if (stat && stat.isFile()) {
    return path;
  }
};

然後就會知道他對檔案的判斷是這一塊

function tryStat(path) {
  debug('stat "%s"', path);

  try {
    return fs.statSync(path);
  } catch (e) {
    return undefined;
  }
}

那接下來要做驗證就很簡單了
我們只要去看一下他怎麼樣判斷檔案然後報錯
試著用一樣的方式就可以簡單地抓到問題點跟重現了
(最後你就會看到Error: ENOENT: no such file or directory, stat '/users/henry/Desktop/complex_app/views/home_guest.ejs'
(因為我有翻這些,加上你的平台是 mac 所以在 facebook 我才會表示 - 跟 _ 沒關係 XDD)

然後你可以再把專案的路徑跟結構貼上來看看,說不定就會發現點什麼

@henry1491491
Copy link
Author

lib/view.js #L52

專案路徑跟結構是這個嗎?
截圖 2019-10-28 下午9 30 52

感謝細心解說,原先 debug 都只會看寫有自己檔案的部分,不知道還可以從其他條錯誤訊息去找 node_module 裡面 express 的內容,應該說是跳出太多條,也不知從何下手。現在知道可以這樣去找關聯性。

@yckao
Copy link

yckao commented Oct 28, 2019

lib/view.js #L52

專案路徑跟結構是這個嗎?
截圖 2019-10-28 下午9 30 52

感謝細心解說,原先 debug 都只會看寫有自己檔案的部分,不知道還可以從其他條錯誤訊息去找 node_module 裡面 express 的內容,應該說是跳出太多條,也不知從何下手。現在知道可以這樣去找關聯性。

恩恩,基本上可以從有關聯的地方去尋找,把問題抓得越清楚,就越容易用正確的方法解決問題

另外這張圖是舊的吧?
home-guest 不是改成 home_guest 了嗎 @@?

@henry1491491
Copy link
Author

lib/view.js #L52

專案路徑跟結構是這個嗎?
截圖 2019-10-28 下午9 30 52
感謝細心解說,原先 debug 都只會看寫有自己檔案的部分,不知道還可以從其他條錯誤訊息去找 node_module 裡面 express 的內容,應該說是跳出太多條,也不知從何下手。現在知道可以這樣去找關聯性。

恩恩,基本上可以從有關聯的地方去尋找,把問題抓得越清楚,就越容易用正確的方法解決問題

另外這張圖是舊的吧?
home-guest 不是改成 home_guest 了嗎 @@?

後來你說跟 _ 沒關係,我又改回來,然後這是目前的

@yckao
Copy link

yckao commented Oct 28, 2019

但你 code 裡面還是 _ 啊 OAO

@henry1491491
Copy link
Author

但你 code 裡面還是 _ 啊 OAO

我應該是全都改過來了誒??
截圖 2019-10-28 下午9 41 43

@henry1491491
Copy link
Author

henry1491491 commented Oct 28, 2019

另外你說權限的部分,是指這個東西嗎??

以下是 views 資料夾的
截圖 2019-10-28 下午9 43 17

@yckao
Copy link

yckao commented Oct 28, 2019

但你 code 裡面還是 _ 啊 OAO

我應該是全都改過來了誒??
截圖 2019-10-28 下午9 41 43

但你看你的錯誤訊息,他是用 - 去看喔 OAO

我在懷疑你會不會做了跟我朋友一樣的事情
(把專案路徑移動之後,編輯器開的根 terminal 開的不一樣)
(強烈建議你檢查一下)

@henry1491491
Copy link
Author

我重跑過了,應該是沒錯!
terminal 是 VSCode 內建的
截圖 2019-10-28 下午9 45 58
截圖 2019-10-28 下午9 47 15

@yckao
Copy link

yckao commented Oct 28, 2019

把這段的路徑

const fs = require('fs')
fs.statSync('/Users/henry/Desktop/complex_app/views/home_guest.ejs').isFile()

換成你上面 stat 給的那個路徑(直接複製貼上)跑跑看吧?

@henry1491491
Copy link
Author

const fs = require('fs')
fs.statSync('/Users/henry/Desktop/complex_app/views/home_guest.ejs').isFile()

結果還是跳錯 XD

截圖 2019-10-28 下午9 58 54

@poying
Copy link

poying commented Oct 28, 2019

@henry1491491 把專案放上 github,別人會比較方便幫忙看問題

@henry1491491
Copy link
Author

@henry1491491 把專案放上 github,別人會比較方便幫忙看問題

馬上補!專案

@poying
Copy link

poying commented Oct 28, 2019

@henry1491491home-guest.ejs 的檔名前面多了一個空格。

你實際檔案路徑是 /Users/henry/Desktop/complex_app/views/ home_guest.ejs
但程式讀取的是 /Users/henry/Desktop/complex_app/views/home_guest.ejs

改名後就可正常運作

螢幕快照 2019-10-28 下午10 47 22

@henry1491491
Copy link
Author

@henry1491491home-guest.ejs 的檔名前面多了一個空格。

你實際檔案路徑是 /Users/henry/Desktop/complex_app/views/ home_guest.ejs
但程式讀取的是 /Users/henry/Desktop/complex_app/views/home_guest.ejs

改名後就可正常運作

螢幕快照 2019-10-28 下午10 47 22

感謝!,問題已解決,結果竟然是空格的問題⋯⋯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants