¿Renderizar vista HTML básica?

279

Tengo una aplicación básica de node.js que intento despegar usando Express Framework. Tengo una viewscarpeta donde tengo un index.htmlarchivo. Pero recibo el siguiente error al cargar el navegador web.

Error: no se puede encontrar el módulo 'html'

Abajo está mi código.

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

app.use(express.staticProvider(__dirname + '/public'));

app.get('/', function(req, res) {
    res.render('index.html');
});

app.listen(8080, '127.0.0.1')

¿Que me estoy perdiendo aqui?

aherrick
fuente

Respuestas:

298

Puede hacer que jade incluya una página HTML simple:

en views / index.jade

include plain.html

en vistas / plain.html

<!DOCTYPE html>
...

y app.js aún puede representar jade:

res.render(index)
Andrew Homeyer
fuente
1
Solo para notar que lo que quiero es servir solo un archivo .html porque mi aplicación era de una sola página;)
diosney
1
¿Podemos incluir múltiples páginas HTML / JS con este método?
user3398326
66
¿no deberías poder renderizar esa página html sin una plantilla de jade solo para la prueba inicial de express?
PositiveGuy
1
Entonces, ¿tenemos que crear una plantilla de jade para cada uno de nuestros archivos HTML?
Chris - Jr
44
Más un truco que una solución.
Ozil
226

Muchas de estas respuestas están desactualizadas.

Usando express 3.0.0 y 3.1.0, funciona lo siguiente:

app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);

Consulte los comentarios a continuación para obtener una sintaxis alternativa y advertencias para express 3.4+:

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

Entonces puedes hacer algo como:

app.get('/about', function (req, res)
{
    res.render('about.html');
});

Esto supone que tiene sus vistas en la viewssubcarpeta y que ha instalado el ejsmódulo de nodo. De lo contrario, ejecute lo siguiente en una consola Node:

npm install ejs --save
Drew Noakes
fuente
@MichaelDausmann, saludos, he incluido esa información en la respuesta.
Drew Noakes
¿Por qué res.render requiere la extensión .html en este caso pero no en el caso predeterminado con jade? con el código repetitivo, solo llama a res.render ('index', {title: 'Express'}); pero aquí, es: res.render ('about.html');
Trascendencia
66
Con Express 3.4.2: app.set ('view engine', 'ejs');
roland
3
Debe usar el comando 'npm install ejs --save' para actualizar su paquete
Tom Teman
8
¿Por qué necesitas ejs?
PositiveGuy
71

De la Guía Express.js: Ver representación

Ver nombres de archivos toman el formulario Express.ENGINE, donde ENGINEestá el nombre del módulo que se requerirá. Por ejemplo, la vista layout.ejsle indicará al sistema de visualización querequire('ejs') el módulo que se está cargando debe exportar el métodoexports.render(str, options) para cumplir con Express, sin embargo, app.register()se puede utilizar para asignar motores a extensiones de archivo, de modo que foo.htmlJade pueda representarlo.

Entonces, o creas tu propio renderizador simple o simplemente usas jade:

 app.register('.html', require('jade'));

Más acerca app.register.

Tenga en cuenta que en Express 3, este método cambia de nombre app.engine

Ivo Wetzel
fuente
57
Nota: app.register ha cambiado su nombre a app.engine en Express 3.
Spongeboy
8
Ver respuesta de Andrew Homeyer. Es la respuesta real.
David Betz
77
De otra respuesta, para Express 4 terminé usandoapp.engine('.html', require('ejs').renderFile);
CrazyPyro el
En express 4, también puede usar: app.set ('view engine', 'jade');
Daniel Huang
48

También puede leer el archivo HTML y enviarlo:

app.get('/', (req, res) => {
    fs.readFile(__dirname + '/public/index.html', 'utf8', (err, text) => {
        res.send(text);
    });
});
keegan3d
fuente
23
esta solución es mala porque no hay almacenamiento en caché de los archivos; se lee para cada solicitud.
Marcel Falliere
2
es potencialmente bastante fácil almacenarlo en caché manualmente. Simplemente almacene una variable en el archivo de lectura, y solo lea nuevamente, si esa variable está en blanco. También puede usar un objeto JS y almacenar varios archivos en varias variables, con marcas de tiempo. Claro que es más trabajo que la mayoría de la gente, pero es bueno con personas nuevas en el nodo. Es fácil de entender
Naman Goel el
55
Yikes Esto derrota todo el punto de las arquitecturas simplificadas y orientadas a convenciones (como MVC).
David Betz
@MarcelFalliere Asume que quiere almacenar en caché el archivo o que no quiere usar una solución de almacenamiento en caché personalizada. Gracias keegan3d por la respuesta.
Benny
@MarcelFalliere Entonces, ¿cuál es la solución correcta? Veo otras respuestas que requieren nuevas dependencias. ¿Es necesario solo para servir archivos html?
JCarlosR
45

prueba esto. esto funciona para mi.

app.configure(function(){

  .....

  // disable layout
  app.set("view options", {layout: false});

  // make a custom html template
  app.register('.html', {
    compile: function(str, options){
      return function(locals){
        return str;
      };
    }
  });
});

....

app.get('/', function(req, res){
  res.render("index.html");
});
espectro
fuente
2
tuve problemas con la configuración exacta anterior, así que eliminé el punto de ".html" y agregué esto: app.set ('view engine', 'html'); app.set ('vistas', __dirname + '/ vistas'); para un render perfecto
Bijou Trouvaille
8
Esto es un poco extraño ... deberías servir html como archivos estáticos. Esto también le brinda el beneficio de un mejor almacenamiento en caché. Crear un "compilador html" personalizado parece incorrecto. Si necesita enviar un archivo desde una ruta (lo que rara vez necesita hacer) simplemente léalo y envíelo. De lo contrario, simplemente redirija al html estático.
enyo
2
@Enyo este comentario parece extraño, teniendo en cuenta CÓMO hacer lo que usted dice que se debe hacer es LA PREGUNTA QUE SE HACE, y su respuesta es simplemente hacerlo. ¿Cómo se sirve un html estático con almacenamiento en caché?
Kyeotic
3
Veo un error en app.register. ¿Quizás ha quedado en desuso en express 3.0.0.rc3? TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
Drew Noakes
1
@enyo, te perdiste el punto de la arquitectura vaporizada. Cuando el patrón es controlador / vista (o / procesador / vista, sea cual sea su arquitectura específica), no puede desviarse de eso con el modelo obsoleto de extensiones. Debe tratar su HTML como contenido renderizado como todo lo demás. Mantenlo SECO, amigo.
David Betz
22
app.get('/', function (req, res) {
res.sendfile(__dirname + '/public/index.html');
});
cabecear
fuente
55
sendfile no es caché en modo producción, por lo que esta no es una buena solución.
Teo Choong Ping
1
@SeymourCakes Por favor, corríjame si me equivoco, pero creo que sendFile ahora admite el almacenamiento en caché: devdocs.io/express/index#res.sendFile
KhoPhi
19

Si está utilizando express@~3.0.0, cambie la línea a continuación de su ejemplo:

app.use(express.staticProvider(__dirname + '/public'));

a algo como esto:

app.set("view options", {layout: false});
app.use(express.static(__dirname + '/public'));

Lo hice como se describe en la página api express y funciona a las mil maravillas. Con esa configuración, no tiene que escribir código adicional, por lo que es bastante fácil de usar para su microproducción o prueba.

Código completo listado a continuación:

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

app.set("view options", {layout: false});
app.use(express.static(__dirname + '/public'));

app.get('/', function(req, res) {
    res.render('index.html');
});

app.listen(8080, '127.0.0.1')
Mark Karwowski
fuente
1
¿Por qué repites app.use(express.static(__dirname + '/public'));después de iniciar el servidor con app.listen?
fatuhoku
2
¿Cuál es la diferencia de servir la página html como estática frente a cargarla no estática con express?
PositiveGuy
14

También enfrenté el mismo problema en express 3.Xy node 0.6.16. La solución dada anteriormente no funcionará para la última versión express 3.x. Quitaron el app.registermétodo y el método agregado app.engine. Si probó la solución anterior, puede terminar con el siguiente error.

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
    at Function.<anonymous> (/home/user1/ArunKumar/firstExpress/app.js:37:5)
    at Function.configure (/home/user1/ArunKumar/firstExpress/node_modules/express/lib/application.js:399:61)
    at Object.<anonymous> (/home/user1/ArunKumar/firstExpress/app.js:22:5)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:31)
    at Function._load (module.js:308:12)
    at Array.0 (module.js:479:10)
    at EventEmitter._tickCallback (node.js:192:40)

Para deshacerse del mensaje de error. Agregue la siguiente línea a suapp.configure function

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

Nota: tienes que instalar el ejsmotor de plantillas

npm install -g ejs

Ejemplo:

app.configure(function(){

  .....

  // disable layout
  app.set("view options", {layout: false});

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

....

app.get('/', function(req, res){
  res.render("index.html");
});

Nota: La solución más simple es usar la plantilla ejs como motor de vista. Allí puede escribir HTML sin formato en archivos de vista * .ejs.

Jak
fuente
3
¿Tienes que instalar ejsglobalmente?
Drew Noakes
es decirme que no puede encontrar el archivo 'index.html'
MetaGuru
9

estructura de carpetas:

.
├── index.html
├── node_modules
   ├──{...}
└── server.js

server.js

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

app.use(express.static('./'));

app.get('/', function(req, res) {
    res.render('index.html');
});

app.listen(8882, '127.0.0.1')

index.html

<!DOCTYPE html>
<html>
<body>

<div> hello world </div>

</body>
</html>

salida:

Hola Mundo

KARTHIKEYAN.A
fuente
7

Si no tiene que usar el directorio de vistas , simplemente mueva los archivos html al directorio público a continuación.

y luego, agregue esta línea en app.configure en lugar de '/ views'.

server.use (express.static (__ dirname + '/ public'));
espectro
fuente
5

Para representar la página HTML en el nodo, intente lo siguiente,

app.set('views', __dirname + '/views');

app.engine('html', require('ejs').renderFile);
  • Necesita instalar el ejsmódulo a través de npmcomo:

       npm install ejs --save
Troyano
fuente
Esta solución funcionó para mí. Aunque también probé la opción estática. ¿Puedes explicar el mecanismo detrás de esto? ¡Gracias!
harshad
4

Para mi proyecto, he creado esta estructura:

index.js
css/
    reset.css
html/
    index.html

Este código sirve index.html para /solicitudes y reset.css para /css/reset.csssolicitudes. Suficientemente simple, y la mejor parte es que agrega automáticamente encabezados de caché .

var express = require('express'),
    server = express();

server.configure(function () {
    server.use('/css', express.static(__dirname + '/css'));
    server.use(express.static(__dirname + '/html'));
});

server.listen(1337);
Znarkus
fuente
3

1) La mejor manera es configurar una carpeta estática. En su archivo principal (app.js | server.js | ???):

app.use(express.static(path.join(__dirname, 'public')));

public / css / form.html
public / css / style.css

Luego tienes el archivo estático de la carpeta "pública":

http://YOUR_DOMAIN/form.html
http://YOUR_DOMAIN/css/style.css

2)

Puedes crear tu caché de archivos.
Utilice el método fs.readFileSync

var cache = {};
cache["index.html"] = fs.readFileSync( __dirname + '/public/form.html');

app.get('/', function(req, res){    
    res.setHeader('Content-Type', 'text/html');
    res.send( cache["index.html"] );                                
};);
Tomáš
fuente
¡no está mal! ¡Aquí hay una demostración de archivo completa! https://gist.github.com/xgqfrms-GitHub/7697d5975bdffe8d474ac19ef906e906
xgqfrms
3

Con Express 4.0.0, lo único que tiene que hacer es comentar 2 líneas en app.js:

/* app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade'); */ //or whatever the templating engine is.

Y luego suelte su archivo estático en el directorio / public. Ejemplo: /public/index.html

u84six
fuente
3

Agregué debajo de la línea 2 y funciona para mí

    app.set('view engine', 'html');
    app.engine('html', require('ejs').renderFile);
Naren Chejara
fuente
me da el siguiente error "Error: no se puede encontrar el módulo 'ejs' en Function.Module._resolveFilename (module.js: 338: 15) en Function.Module._load (module.js: 280: 25) en Module.require ( module.js: 364: 17) en require (module.js: 380: 17) "
Lygub Org
@LygubOrg se ejecuta npm install ejs --saveen su directorio de trabajo.
A1rPun
1
¿es necesario agregar una dependencia solo para servir un archivo html?
JCarlosR
3

Pruebe la función res.sendFile () en rutas Express.

var express = require("express");
var app     = express();
var path    = require("path");


app.get('/',function(req,res){
  res.sendFile(path.join(__dirname+'/index.html'));
  //__dirname : It will resolve to your project folder.
});

app.get('/about',function(req,res){
  res.sendFile(path.join(__dirname+'/about.html'));
});

app.get('/sitemap',function(req,res){
  res.sendFile(path.join(__dirname+'/sitemap.html'));
});

app.listen(3000);

console.log("Running at Port 3000");

Lea aquí: http://codeforgeek.com/2015/01/render-html-file-expressjs/

Shaikh Shahid
fuente
3

No quería depender de ejs para simplemente entregar un archivo HTML, así que simplemente escribí el pequeño renderizador:

const Promise = require( "bluebird" );
const fs      = Promise.promisifyAll( require( "fs" ) );

app.set( "view engine", "html" );
app.engine( ".html", ( filename, request, done ) => {
    fs.readFileAsync( filename, "utf-8" )
        .then( html => done( null, html ) )
        .catch( done );
} );
Der Hochstapler
fuente
2

Intenté configurar una aplicación angular con una API RESTful exprés y aterricé en esta página varias veces, aunque no fue útil. Esto es lo que encontré que funcionó:

app.configure(function() {
    app.use(express.static(__dirname + '/public'));         // set the static files location
    app.use(express.logger('dev'));                         // log every request to the console
    app.use(express.bodyParser());                          // pull information from html in POST
    app.use(express.methodOverride());                      // simulate DELETE and PUT
    app.use(express.favicon(__dirname + '/public/img/favicon.ico'));
});

Luego, en la devolución de llamada para sus rutas de API se ven así: res.jsonp(users);

Su marco del lado del cliente puede manejar el enrutamiento. Express es para servir a la API.

Mi ruta local se ve así:

app.get('/*', function(req, res) {
    res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});
Connor Leech
fuente
2
res.sendFile(__dirname + '/public/login.html');
himanshu yadav
fuente
2

¡Aquí hay una demostración completa del archivo del servidor express!

https://gist.github.com/xgqfrms-GitHub/7697d5975bdffe8d474ac19ef906e906

Espero que te ayude!

// simple express server for HTML pages!
// ES6 style

const express = require('express');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 3000;
const app = express();

let cache = [];// Array is OK!
cache[0] = fs.readFileSync( __dirname + '/index.html');
cache[1] = fs.readFileSync( __dirname + '/views/testview.html');

app.get('/', (req, res) => {
    res.setHeader('Content-Type', 'text/html');
    res.send( cache[0] );
});

app.get('/test', (req, res) => {
    res.setHeader('Content-Type', 'text/html');
    res.send( cache[1] );
});

app.listen(port, () => {
    console.log(`
        Server is running at http://${hostname}:${port}/ 
        Server hostname ${hostname} is listening on port ${port}!
    `);
});

xgqfrms
fuente
1

Agregue las siguientes líneas a su código

  1. Reemplace "jade" con "ejs" y "XYZ" (versión) con "*" en el archivo package.json

      "dependencies": {
       "ejs": "*"
      }
  2. Luego, en su archivo app.js, agregue el siguiente código:

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

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

  3. Y recuerde mantener todos los archivos .HTML en la carpeta de vistas

Salud :)

Amulya Kashyap
fuente
1

Para html simple, no necesita ningún paquete npm o middleware

solo usa esto:

app.get('/', function(req, res) {
    res.sendFile('index.html');
});
Shivam Chhetri
fuente
1

Es muy triste que sea alrededor de 2020 y todavía express no haya agregado una forma de representar una página HTML sin usar el sendFilemétodo del responseobjeto. Usar sendFileno es un problema, pero pasar un argumento en forma de path.join(__dirname, 'relative/path/to/file')no parece correcto. ¿Por qué debería un usuario unirse __dirnamea la ruta del archivo? Debe hacerse por defecto. ¿Por qué la raíz del servidor no puede ser desactivando el directorio del proyecto? Además, instalar una dependencia de plantillas solo para representar un archivo HTML estático no es correcto nuevamente. No sé la forma correcta de abordar el problema, pero si tuviera que servir un HTML estático, entonces haría algo como:

const PORT = 8154;

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

app.use(express.static('views'));

app.listen(PORT, () => {
    console.log(`Server is listening at port http://localhost:${PORT}`);
});

El ejemplo anterior supone que la estructura del proyecto tiene un viewsdirectorio y que los archivos HTML estáticos están dentro de él. Por ejemplo, digamos, el viewsdirectorio tiene dos archivos HTML nombrados index.htmly about.html, para acceder a ellos, podemos visitar: localhost:8153/index.htmlo simplemente localhost:8153/para cargar la index.htmlpágina y localhost:8153/about.htmlcargar el archivo about.html. Podemos usar un enfoque similar para servir una aplicación de reacción / angular almacenando los artefactos en el viewsdirectorio o simplemente usando el dist/<project-name>directorio predeterminado y configúrelo en el servidor js de la siguiente manera:

app.use(express.static('dist/<project-name>'));
Vighnesh Raut
fuente
0

Quería permitir que las solicitudes a "/" sean manejadas por una ruta Express donde previamente habían sido manejadas por el middleware estático. Esto me permitiría renderizar la versión normal de index.html o una versión que cargara JS y CSS concatenados + minificados, dependiendo de la configuración de la aplicación. Inspirado por la respuesta de Andrew Homeyer , decidí arrastrar mis archivos HTML, sin modificar, a una carpeta de vistas, configurar Express así

   app.engine('html', swig.renderFile);
   app.set('view engine', 'html');
   app.set('views', __dirname + '/views');  

Y creó un controlador de ruta así

 app.route('/')
        .get(function(req, res){
            if(config.useConcatendatedFiles){
                return res.render('index-dist');
            }
            res.render('index');       
        });

Esto funcionó bastante bien.

K. Francis
fuente
0

En server.js, incluya

var express = require("express");
var app     = express();
var path    = require("path");


app.get('/',function(req,res){
  res.sendFile(path.join(__dirname+'/index.html'));
  //__dirname : It will resolve to your project folder.
});
shumana chowdhury
fuente
0

Si está tratando de servir un archivo HTML que YA tiene todo su contenido dentro, entonces no necesita ser 'renderizado', solo necesita ser 'servido'. La representación se produce cuando el servidor actualiza o inyecta contenido antes de enviar la página al navegador, y requiere dependencias adicionales como ejs, como muestran las otras respuestas.

Si simplemente desea dirigir el navegador a un archivo en función de su solicitud, debe usar res.sendFile () de esta manera:

const express = require('express');
const app = express();
var port = process.env.PORT || 3000; //Whichever port you want to run on
app.use(express.static('./folder_with_html')); //This ensures local references to cs and js files work

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/folder_with_html/index.html');
});

app.listen(port, () => console.log("lifted app; listening on port " + port));

De esta manera, no necesita dependencias adicionales además de express. Si solo desea que el servidor envíe sus archivos html ya creados, lo anterior es una forma muy ligera de hacerlo.

aleph_one
fuente
0

index.js

var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));


app.get('/', function(req, res) {
    res.render('index.html');
});


app.listen(3400, () => {
    console.log('Server is running at port 3400');
})

Pon tu archivo index.html en una carpeta pública

<!DOCTYPE html>
<html>
<head>
    <title>Render index html file</title>
</head>
<body>
    <h1> I am from public/index.html </h1>
</body>
</html>

Ahora ejecuta el siguiente código en tu terminal

nodo index.js

Ahmad Sharif
fuente
-1

Usualmente uso esto

app.configure(function() {
    app.use(express.static(__dirname + '/web'));
});

Solo tenga cuidado porque eso compartirá cualquier cosa en el directorio / web.

Espero que ayude

DiogoNeves
fuente
-2

si está utilizando express framework para node.js

instalar npm ejs

luego agregue el archivo de configuración

app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router)

;

renderice la página desde el módulo de exportaciones form.js tenga el archivo html en el directorio de vistas con la extensión del nombre del archivo ejs como form.html.ejs

luego crea el form.js

res.render('form.html.ejs');

aruneshtechno
fuente
¿Qué es este desastre?
Vighnesh Raut