Error: no se especificó ningún motor predeterminado y no se proporcionó ninguna extensión

132

Estoy trabajando para configurar un servidor http usando node.js y engine. Sin embargo, sigo encontrando problemas con los que tengo poca información sobre cómo resolverlos, agradecería un poco de ayuda para resolver esto, por favor.

Error: No default engine was specified and no extension was provided. 
at new View (...\node_modules\express\lib\view.js:41:42) 
at Function.app.render (...\node_modules\express\lib\application.js:484:12) 
at ServerResponse.res.render (...\node_modules\express\lib\response.js:783:7) 
at Layer.handle (...\app.js:123:7) 
at trim_prefix (...\node_modules\express\lib\router\index.js:225:17) 
at c (...\node_modules\express\lib\router\index.js:198:9) 
at Function.proto.process_params (...\node_modules\express\lib\router\index.js:253:12) 
at next (...\node_modules\express\lib\router\index.js:189:19) 
at next (...\node_modules\express\lib\router\index.js:202:7) 
at next (...\node_modules\express\lib\router\index.js:166:38)

A continuación se muestra lo que he configurado para iniciar este motor.

var http = require('http');  
var module = require("module")
var logger = require('morgan');
var express = require('express');
var app =  module.exports = express();
var silent = 'test' == process.env.NODE_ENV;
var httpServer = http.createServer(app);  // app middleware

app.enable('strict routing');
// app.all('*', function(req, res, next)/*** CORS support.*/
// {
//   if (!req.get('Origin')) return next();// use "*" here to accept any origin
//   res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
//   res.set('Access-Control-Allow-Methods', 'GET, POST');
//   res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
//   res.set('Access-Control-Allow-Max-Age', 3600);
//   if ('OPTIONS' == req.method) return res.send(200);
//   next();
// });
app.set('views', __dirname + '/views'); // general config
app.set('view engine', 'html');
app.get('/404', function(req, res, next){
next();// trigger a 404 since no other middleware will match /404 after this one, and we're not responding here
});
app.get('/403', function(req, res, next){// trigger a 403 error
  var err = new Error('not allowed!');
  err.status = 403;
  next(err);
});
app.get('/500', function(req, res, next){// trigger a generic (500) error
  next(new Error('keyboard cat!'));
});
app.use(express.static(__dirname + '/public')); 
//error handlers
app.use(logErrors);
app.use(clientErrorHandler);
app.use(errorHandler);  
// middleware with an arity of 4 are considered error handling middleware. When you next(err)
// it will be passed through the defined middleware in order, but ONLY those with an arity of 4, ignoring regular middleware.
function clientErrorHandler(err, req, res, next) {
  if (req.xhr) {// whatever you want here, feel free to populate properties on `err` to treat it differently in here.
  res.send(err.status || 500, { error: err.message });
  } 
  else 
  { next(err);}
};
// create an error with .status. we can then use the property in our custom error handler (Connect repects this prop as well)
function error  (status, msg) {
  var err = new Error(msg);
  err.status = status;
  return err;
};
function logErrors  (err, req, res, next) {
  console.error(err.stack);
  next(err);
};
function errorHandler (err, req, res, next) {
  res.status(500);
  res.render('error', { error: err });
};

// Error handlers
// Since this is the last non-error-handling middleware use()d, we assume 404, as nothing else responded.
// $ curl http://localhost:3000/notfound
// $ curl http://localhost:3000/notfound -H "Accept: application/json"
// $ curl http://localhost:3000/notfound -H "Accept: text/plain"
app.use(function(req, res, next){
  res.status(404); 
  if (req.accepts('html')) {// respond with html page
    res.render('404', { url: req.url });
    return;
  } 
  if (req.accepts('json')) {// respond with json
    res.send({ error: 'Not found' });
    return;
  } 
  res.type('txt').send('Not found');// default to plain-text. send()
});

// error-handling middleware, take the same form as regular middleware, however they require an
// arity of 4, aka the signature (err, req, res, next).when connect has an error, it will invoke ONLY error-handling middleware.

// If we were to next() here any remaining non-error-handling middleware would then be executed, or if we next(err) to
// continue passing the error, only error-handling middleware would remain being executed, however here
// we simply respond with an error page.
app.use(function(err, req, res, next){
  // we may use properties of the error object here and next(err) appropriately, or if we possibly recovered from the error, simply next().
  res.status(err.status || 500);
  res.render('500', { error: err });
});

if (!module.parent) {// assigning to exports will not modify module, must use module.exports
  app.listen(3000);
  silent || console.log('Express started on port 3000');
};
Kobojunkie
fuente

Respuestas:

120

El material res.render arrojará un error si no está utilizando un motor de visualización.

Si solo desea servir json, reemplace las res.render('error', { error: err });líneas en su código con:

res.json({ error: err })

PD: las personas generalmente también tienen un mensaje en el objeto devuelto:

res.status(err.status || 500);
res.json({
  message: err.message,
  error: err
});
Pylinux
fuente
102

Te falta el motor de vista, por ejemplo, usa jade :

cambia tu

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

con

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

Si quieres usar una sintaxis amigable html, usa ejs

app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

EDITAR

Como puede leer desde view.js Express View Module

module.exports = View;

/**
 * Initialize a new `View` with the given `name`.
 *
 * Options:
 *
 *   - `defaultEngine` the default template engine name
 *   - `engines` template engine require() cache
 *   - `root` root path for view lookup
 *
 * @param {String} name
 * @param {Object} options
 * @api private
 */

function View(name, options) {
  options = options || {};
  this.name = name;
  this.root = options.root;
  var engines = options.engines;
  this.defaultEngine = options.defaultEngine;
  var ext = this.ext = extname(name);
  if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
  if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
  this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
  this.path = this.lookup(name);
}

Debes haber instalado un default engine

Expressbusque la vista de diseño predeterminada program.templatecomo puede leer a continuación:

mkdir(path + '/views', function(){
      switch (program.template) {
        case 'ejs':
          write(path + '/views/index.ejs', ejsIndex);
          break;
        case 'jade':
          write(path + '/views/layout.jade', jadeLayout);
          write(path + '/views/index.jade', jadeIndex);
          break;
        case 'jshtml':
          write(path + '/views/layout.jshtml', jshtmlLayout);
          write(path + '/views/index.jshtml', jshtmlIndex);
          break;
        case 'hjs':
          write(path + '/views/index.hjs', hoganIndex);
          break;

      }
    });

y como puedes leer a continuación:

program.template = 'jade';
if (program.ejs) program.template = 'ejs';
if (program.jshtml) program.template = 'jshtml';
if (program.hogan) program.template = 'hjs';

el motor de vista predeterminado es jade

alessandro
fuente
2
Hola, ¿puedes explicar cómo funciona esto? Comencé a leer en node.js, pensando que era todo lo que necesitaba, pero cuando aún no podía mostrar mis páginas, busqué por qué y llegué a información sobre express. Ahora seguí la información en la página express 4.2, y me encontré con el error anterior con el que me ayudó. Ahora tengo ejs y todavía no parece ser todo lo que necesito. ¿Puede por favor darme una idea de cómo debería funcionar esto, por favor?
Kobojunkie
Había pensado leer que debe definir explícitamente un motor de vista incluso si está visualizando vistas de representación. Sin embargo, ese no es el caso.
stevejpurves
15

Comente las res.renderlíneas en su código y agregue en su next(err);lugar. Si no está utilizando un motor de visualización, las res.rendercosas arrojarán un error.

Lo sentimos, también tendrás que comentar esta línea:

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

Sin embargo, mi solución resultaría en no usar un motor de visualización. No necesita un motor de visualización, pero si ese es el objetivo, intente esto:

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
//swap jade for ejs etc

También necesitará las res.renderlíneas cuando use un motor de visualización. Algo como esto:

// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
    message: err.message,
    error: err
    });
  });
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  next(err);
  res.render('error', {
  message: err.message,
  error: {}
  });
});
caokey
fuente
12

Si desea renderizar un archivo html, use:

response.sendfile('index.html');

Luego eliminas:

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

Pon tu *.htmlen el viewsdirectorio, o sirve un publicdirectorio como directorio estático y pon el index.htmlen el publicdirectorio.

nivash-IoT
fuente
44
response.sendfile()está en desuso, úselo en su response.sendFile()lugar. Tenga en cuenta que la capital "F".
Pramesh Bajracharya
6

Establecer vista del motor de la siguiente manera

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
KARTHIKEYAN.A
fuente
4

Si todo lo que se necesita es enviar el código html en línea en el código, podemos usar a continuación

var app = express();
app.get('/test.html', function (req, res) {
   res.header('Content-Type', 'text/html').send("<html>my html code</html>");
});
Dinesh Rajan
fuente
0

Acabo de recibir este mensaje de error, y el problema era que no estaba configurando mi middleware correctamente.

Estoy construyendo un blog en la pila MEAN y necesitaba analizar el cuerpo para los archivos .jade que estaba usando en el lado frontal. Aquí está el fragmento de código de mi archivo " /middleware/index.js ", de mi proyecto.

var express = require('express');
var morgan = require('morgan');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

module.exports = function (app) {
app.use(morgan('dev'));

// Good for now
// In the future, use connect-mongo or similar
// for persistant sessions
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(cookieParser());
app.use(session({secret: 'building a blog', saveUninitialized: true, resave: true}));

Además, aquí está mi archivo " package.json ", puede estar utilizando diferentes versiones de tecnologías. Nota: debido a que no estoy seguro de las dependencias entre ellos, incluyo el archivo completo aquí:

"dependencies": {
    "body-parser": "1.12.3",
    "consolidate": "0.12.1",
    "cookie-parser": "1.3.4",
    "crypto": "0.0.3",
    "debug": "2.1.1",
    "express": "4.12.2",
    "express-mongoose": "0.1.0",
    "express-session": "1.11.1",
    "jade": "1.9.2",
    "method-override": "2.3.2",
    "mongodb": "2.0.28",
    "mongoose": "4.0.2",
    "morgan": "1.5.1",
    "request": "2.55.0",
    "serve-favicon": "2.2.0",
    "swig": "1.4.2"
  }

¡Espero que esto ayude a alguien! ¡Todo lo mejor!

Mihnea
fuente
0

Las respuestas anteriores son correctas, pero descubrí que un error tipográfico simple también puede generar este error. Por ejemplo, tuve var router = express () en lugar de var router = express.Router () y obtuve este error. Entonces debería ser lo siguiente:

// App.js 
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended:false}));
// assuming you put views folder in the same directory as app.js
app.set('views', __dirname + '/views')
app.engine('ejs', ejs.renderFile);
app.set('view engine', 'ejs');
// router - wherever you put it, could be in app.js
var router = express.Router();
router.get('/', function (req,res) {
  res.render('/index.ejs');
})
evanjmg
fuente
0

Puede usar express-error-handler para usar páginas html estáticas para el manejo de errores y evitar definir un manejador de vistas.

El error probablemente fue causado por un 404, tal vez un favicon faltante (aparente si había incluido el mensaje anterior de la consola). El 'controlador de vista' de 'html' no parece ser válido en 4.x express.

Independientemente de la causa, puede evitar definir un controlador de vista (válido) siempre que modifique elementos adicionales de su configuración.

Sus opciones son para solucionar este problema son:

  • Definir un controlador de vista válido como en otras respuestas
  • Use send () en lugar de render para devolver el contenido directamente

http://expressjs.com/en/api.html#res.render

El uso de render sin una ruta de archivo invoca automáticamente un controlador de vista como con las siguientes dos líneas de su configuración:

res.render('404', { url: req.url });

y:

res.render('500);

Asegúrate de instalar express-error-handler con:

npm install --save express-error-handler

Luego impórtalo en tu app.js

var ErrorHandler = require('express-error-handler');

Luego cambie su manejo de errores para usar:

// define below all other routes
var errorHandler = ErrorHandler({
  static: {
    '404': 'error.html' // put this file in your Public folder
    '500': 'error.html' // ditto
});

// any unresolved requests will 404
app.use(function(req,res,next) {
  var err = new Error('Not Found');
  err.status(404);
  next(err);
}

app.use(errorHandler);
Chanoch
fuente
0

Simplemente configure el motor de vista en su código.

var app = express(); 
app.set('view engine', 'ejs');
jatin sablok
fuente
0

Error: no se especificó ningún motor predeterminado y no se proporcionó ninguna extensión

Tengo el mismo problema (por hacer un proyecto de stack medio) ... el problema es que no mencioné el formato para instalar npm, es decir; pug o jade, ejs, etc., para resolver este goto npm e ingrese express --view = pug foldername. Esto cargará los archivos pug necesarios (index.pug, layout.pug, etc.) en su carpeta dada.

Bhargava Gidijala
fuente
0

si tienes este error usando el generador express, lo he resuelto usando

express --view=ejs myapp

en vez de

express --view=pug myapp
Puesto de Tiago da Silva
fuente