nodejs-tw / ama

Ask me anything!
MIT License
31 stars 1 forks source link

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

Open henry1491491 opened 4 years ago

henry1491491 commented 4 years ago

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

目的

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

使用的工具

目前開發環境:

專案連結

連結

操作流程

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

截圖 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', 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 樣板引擎這邊的完整程式碼(沒有自己更動過),然後就跳出錯誤
```js
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 commented 4 years ago

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

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

henry1491491 commented 4 years ago

可以檢查一下 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 commented 4 years ago

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

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

--

更正一下 npm ls 也可以

yckao commented 4 years ago
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 commented 4 years ago

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

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

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

henry1491491 commented 4 years ago
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 commented 4 years ago
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 commented 4 years ago
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 commented 4 years ago

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

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

你跑起來有去 localhost:3000 嗎?

henry1491491 commented 4 years ago

不好意思⋯⋯ 不過我在 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 commented 4 years ago

一樣是這段!

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 commented 4 years ago

一樣是這段!

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 裡面的東西完整的貼上來...

是的,我照你的方式做了

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

yckao commented 4 years ago

截圖 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 commented 4 years ago

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 commented 4 years ago

其實整個的思路是這樣 我一開始是在看錯誤從哪邊拋出 從錯誤訊息找會找到 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 commented 4 years ago

lib/view.js #L52

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

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

yckao commented 4 years ago

lib/view.js #L52

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

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

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

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

henry1491491 commented 4 years ago

lib/view.js #L52

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

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

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

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

yckao commented 4 years ago

但你 code 裡面還是 _ 啊 OAO

henry1491491 commented 4 years ago

但你 code 裡面還是 _ 啊 OAO

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

henry1491491 commented 4 years ago

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

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

yckao commented 4 years ago

但你 code 裡面還是 _ 啊 OAO

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

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

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

henry1491491 commented 4 years ago

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

yckao commented 4 years ago

把這段的路徑

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

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

henry1491491 commented 4 years ago
const fs = require('fs')
fs.statSync('/Users/henry/Desktop/complex_app/views/home_guest.ejs').isFile()

結果還是跳錯 XD

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

poying commented 4 years ago

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

henry1491491 commented 4 years ago

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

馬上補!專案

poying commented 4 years ago

@henry1491491 你 home-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 commented 4 years ago

@henry1491491 你 home-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

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