2016-12-02 3 views
2

Как первое, что я когда-либо пытался использовать NodeJS, я создаю простое приложение, которое отображает страницу HTML, которая сообщает посетителям об их IP-адресе.TypeError: this.engine не является функцией при попытке использования Mustache в Express JS

Вот как это выглядит

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 

Я уже установил frontPage.html внутри views/ и я a уже установлен Усы из НПМ (npm install mu2 --save). Что в этом плохого?

+1

После некоторых исследований я обнаружил некоторые несоответствия в отношении совместимости Express с Усы. Даже когда руководство на веб-сайте говорит, что оно совместимо, Mustache отсутствует в этом списке: https://github.com/expressjs/express/wiki?_ga=1.74621138.1527575629.1480681917#template-engines – starleaf1

ответ

1

я в конечном итоге в обход системы шаблонов Express' и использовать Усы собственного 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"); 
}); 

Это работает сейчас.

0

Необходимо изменить расширение файла с .html на .mu2. res.render('frontPage.mu2', { ip: req.ip});, так как файл Mustache не является файлом HTML. Вы также можете оставить расширение файла выключенным с момента установки рендерера представления по умолчанию на mu2, а выражение будет использовать это как механизм рендеринга, если не предусмотрено расширение файла. Нравится 0 ... res.render('frontPage', {ip: req.ip});. Обратите внимание, что первая часть - это путь к файлу '/ frontPage', а вторая часть - это локальный объект, который вы передаете в шаблон. Вы получите доступ к свойству ip этого объекта примерно так: {{ip}} внутри вашего файла .mu2. Усы возвращает отображаемый HTML для выражения, а res.render отправляет его на клиенте.

Кроме того, вам не требуется res.send(), поскольку res.render() отображает представление и отправляет визуализированную строку HTML клиенту, а так как text/html также принимается в ответах или тип String, вам не нужен 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.

+0

Итак, я опустил объявление заголовка , 'send()' и расширение файла шаблона. Я также переименовал 'frontPage.html' в' frontPage.mu2' добавленный '/' в начало 'view'. Вся строка теперь читает 'res.render ('/ frontPage', {ip: req.ip});« К сожалению, теперь он говорит мне «Не удалось найти просмотр»/frontPage в каталоге представлений »/ Users/macuser/NodeJS/hello/views "' – starleaf1

+0

Пробовал ли вы без "/"? res.render ('frontPage', {ip: req.ip}); – quarterpi

+0

Возврат к исходной ошибке. – starleaf1

Смежные вопросы