TypeError: this.engine is not a function when trying to use Moustache in Express JS

TypeError: this.engine is not a function when trying to use Moustache in Express JS

作为我在 NodeJS 上尝试的第一件事,我正在构建一个简单的应用程序,它显示一个 HTML 页面,告诉访问者他们的 IP 地址。

这是它的样子

var express = require('express');
var app = express();

app.set('view engine', 'mu2');

app.get('/', function (req, res) {
    res.setHeader('Content-Type', 'text/html');    // Do I have to do this? I'm not sure.
    res.render('frontPage.html', {
        ip: req.ip
    });
res.send();
});

app.listen(8080, function() {
    console.log("Listening on port 8080");
});

下面是 /views/frontPage.html 的样子:

<!DOCTYPE html>
<html>
    <head>
        <title>Hello, World!</title>
    </head>
    <body>
        <h1>Hello, World!</h1>
        <hr>
        <p>If you're reading this, the NodeJS setup is working. Check your developer console. See if there's any HTTP error in there.</p>
        <p>Anyway, your IP address is {{ip}}</p>
    </body>
</html>

这是我每次发送请求时在控制台中得到的信息:

TypeError: this.engine is not a function
    at View.render (/Users/macuser/NodeJS/hello/node_modules/express/lib/view.js:126:8)
    at tryRender (/Users/macuser/NodeJS/hello/node_modules/express/lib/application.js:639:10)
    at EventEmitter.render (/Users/macuser/NodeJS/hello/node_modules/express/lib/application.js:591:3)
    at ServerResponse.render (/Users/macuser/NodeJS/hello/node_modules/express/lib/response.js:960:7)
    at /Users/macuser/NodeJS/hello/index.js:8:9
    at Layer.handle [as handle_request] (/Users/macuser/NodeJS/hello/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/macuser/NodeJS/hello/node_modules/express/lib/router/route.js:131:13)
    at Route.dispatch (/Users/macuser/NodeJS/hello/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/macuser/NodeJS/hello/node_modules/express/lib/router/layer.js:95:5)
    at /Users/macuser/NodeJS/hello/node_modules/express/lib/router/index.js:277:22

我已经在 views/ 中设置了 frontPage.html 并且我已经从 NPM (npm install mu2 --save) 安装了 Mustache。 怎么了?

您需要将文件扩展名从 .html 更改为 .mu2。 res.render('frontPage.mu2', { ip: req.ip}); 因为它是 Mustache 文件而不是 HTML 文件。您也可以关闭文件扩展名,因为您将默认视图渲染器设置为 mu2,如果没有提供文件扩展名,express 将使用它作为渲染引擎。 像这样……res.render('frontPage', {ip: req.ip});。请注意,第一部分是文件路径“/frontPage”,第二部分是您传递给模板的本地对象。您将在 .mu2 文件中访问该对象的 ip 属性,类似于 {{ip}}。小胡子 returns 渲染 HTML 来表达,并且 res.render 在客户端发送它。

此外,您不需要 res.send(),因为 res.render() 呈现视图,并将呈现的 HTML 字符串发送到客户端,并且由于 text/html 也假定响应或类型为字符串,您不需要 res.setHeader('Content-Type', 'text-html');但要么。 ;)

来自 expressjs.com

res.render(view [, locals] [, callback]) Renders a view and sends the rendered HTML string to the client. Optional parameters:

locals, an object whose properties define local variables for the view.

callback, a callback function. If provided, the method returns both the possible error and rendered string, but does not perform an automated response. When an error occurs, the method invokes next(err) internally.

The view argument is a string that is the file path of the view file to render. This can be an absolute path, or a path relative to the views setting. If the path does not contain a file extension, then the view engine setting determines the file extension. If the path does contain a file extension, then Express will load the module for the specified template engine (via require()) and render it using the loaded module’s __express function.

我最终绕过了 Express 的模板系统并使用了 Mustache 自己的 compileAndRender()。像这样:

var express = require('express');
var app = express();
var mu2 = require('mu2');
mu2.root = __dirname + '/views';

app.get('/', function (req, res) {
    var htmlStream = mu2.compileAndRender('frontPage.html', {ip: req.ip});
    htmlStream.pipe(res);
});

app.listen(8080, function () {
    console.log("Listening on port 8080");
});

现在有效。