Renderizar visualização HTML básica?

279

Eu tenho um aplicativo node.js básico que estou tentando decolar usando o Express framework. Eu tenho uma viewspasta onde eu tenho um index.htmlarquivo. Mas recebo o seguinte erro ao carregar o navegador da web.

Erro: Não foi possível encontrar o módulo 'html'

Abaixo está o meu 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')

O que estou perdendo aqui?

aherrick
fonte

Respostas:

298

Você pode fazer com que o jade inclua uma página HTML simples:

em views / index.jade

include plain.html

em views / plain.html

<!DOCTYPE html>
...

e o app.js ainda pode renderizar jade:

res.render(index)
Andrew Homeyer
fonte
1
Apenas a nota que o que eu queria era para servir apenas um arquivo .html porque meu aplicativo foi única página;)
diosney
1
Podemos incluir várias páginas HTML / JS com esse método?
user3398326
6
você não deveria poder renderizar essa página html sem um modelo de jade apenas para o teste inicial do express?
PositiveGuy
1
Então, precisamos criar um modelo de jade para cada um dos nossos arquivos HTML?
Chris - Jr
4
Mais um hack do que uma solução.
Ozil
226

Muitas dessas respostas estão desatualizadas.

Usando express 3.0.0 e 3.1.0, o seguinte funciona:

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

Consulte os comentários abaixo para obter sintaxe e advertências alternativas para o express 3.4+:

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

Então você pode fazer algo como:

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

Isso pressupõe que você tenha suas visualizações na viewssubpasta e que instalou o ejsmódulo do nó. Caso contrário, execute o seguinte em um console do Node:

npm install ejs --save
Drew Noakes
fonte
@ MichaelDausmann, saúde, incluí essa informação na resposta.
Desenhou Noakes
por que o res.render requer a extensão .html neste caso, mas não no caso padrão com jade. com o código padrão, ele chama apenas res.render ('index', {title: 'Express'}); mas aqui está: res.render ('about.html');
Transcendência
6
Com o Express 3.4.2: app.set ('view engine', 'ejs');
Roland
3
Você deve usar o comando 'npm instalar EJS --save' para atualizar o seu package.json
Tom Temã
8
por que você precisa de ejs?
PositiveGuy
71

No guia Express.js: exibir renderização

Os nomes dos arquivos de exibição assumem o formulário Express.ENGINE, onde ENGINEé o nome do módulo que será necessário. Por exemplo, a visualização layout.ejsinformará o sistema de visualizaçãorequire('ejs') , o módulo que está sendo carregado deve exportar o métodoexports.render(str, options) para estar em conformidade com o Express, no entanto, app.register()pode ser usado para mapear mecanismos para extensões de arquivo, para que, por exemplo, foo.htmlpossa ser renderizado por jade.

Então, você cria seu próprio renderizador simples ou usa o jade:

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

Mais sobre app.register.

Observe que no Express 3, esse método é renomeado app.engine

Ivo Wetzel
fonte
57
App.register nota- foi app.engine renomeado in Express 3.
Spongeboy
8
Veja a resposta de Andrew Homeyer. É a resposta real.
David Betz
7
De alguma outra resposta, pois Express 4 Acabei usandoapp.engine('.html', require('ejs').renderFile);
CrazyPyro
No express 4, você também pode usar: app.set ('view engine', 'jade');
Daniel Huang
48

Você também pode ler o arquivo HTML e enviá-lo:

app.get('/', (req, res) => {
    fs.readFile(__dirname + '/public/index.html', 'utf8', (err, text) => {
        res.send(text);
    });
});
keegan3d
fonte
23
esta solução é ruim porque não há cache dos arquivos; é lido para cada solicitação.
Marcel Falliere
2
é potencialmente muito fácil armazená-lo manualmente. Apenas armazene o arquivo de leitura em uma variável e apenas leia novamente, se essa variável estiver em branco. Você também pode usar um objeto JS e armazenar vários arquivos em várias variáveis, com registro de data e hora. Certamente é mais trabalho do que a maioria das pessoas faria, mas é bom com pessoas novas para o nó. É fácil de entender
Naman Goel
5
Caramba. Isso derrota todo o ponto de arquiteturas otimizadas e orientadas a convenções (como o MVC).
David Betz
@MarcelFalliere Você está assumindo que ele deseja armazenar em cache o arquivo ou que não deseja usar uma solução de cache personalizada. Obrigado keegan3d pela resposta.
Benny
@MarcelFalliere Então, qual é a solução certa? Vejo outras respostas que exigem novas dependências. É necessário apenas para servir arquivos html?
perfil completo de JCarlos
45

tente isso. funciona para mim.

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
fonte
2
tive problemas com a configuração exata acima, então removi o ponto de ".html" e adicionei o seguinte: app.set ('view engine', 'html'); app.set ('views', __dirname + '/ views'); para um perfeito tornar
Bijou Trouvaille
8
Isso é um pouco estranho ... você deve servir html como arquivos estáticos. Isso também oferece o benefício de um melhor cache. Criar um "compilador html" personalizado parece errado. Se você precisar enviar um arquivo de dentro de uma rota (o que raramente é necessário) basta ler e enviá-lo. Caso contrário, basta redirecionar para o html estático.
enyo
2
@ Enyo esse comentário parece estranho, considerando COMO FAZER o que você está dizendo que deve ser feito é a pergunta que está sendo feita, e sua resposta é apenas fazê-lo. Como você serve um html estático com armazenamento em cache?
Kyeotic
3
Vejo um erro no app.register. Talvez tenha sido preterido no express 3.0.0.rc3? TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
Drew Noakes
1
@enyo, você perdeu o ponto da arquitetura simplificada. Quando o padrão é controlador / visão (ou / processador / visão, seja qual for sua arquitetura específica), você não pode se desviar disso com o modelo obsoleto de extensões. Você precisa tratar seu HTML como conteúdo renderizado como todo o resto. Mantenha seco, cara.
David Betz
22
app.get('/', function (req, res) {
res.sendfile(__dirname + '/public/index.html');
});
aceno com a cabeça
fonte
5
sendfile não é cache no modo de produção, portanto, essa não é uma boa solução.
Teo Choong Ping
1
@SeymourCakes favor, me corrija se eu estiver errado, mas acho que SENDFILE agora suporta o armazenamento em cache: devdocs.io/express/index#res.sendFile
KhoPhi
19

Se você estiver usando express@~3.0.0, altere a linha abaixo do seu exemplo:

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

para algo como isto:

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

Eu fiz isso como descrito na página da API expressa e funciona como um encanto. Com essa configuração, você não precisa escrever código adicional, para que seja fácil o suficiente para sua micro produção ou teste.

Código completo listado abaixo:

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
fonte
1
Por que você repete app.use(express.static(__dirname + '/public'));depois de iniciar o servidor app.listen?
Fatuhoku 5/03
2
qual é a diferença de servir a página html como estática versus apenas carregá-la não-estática com o express?
PositiveGuy
14

Eu também enfrentei o mesmo problema em express 3.Xe node 0.6.16. A solução fornecida acima não funcionará na versão mais recente express 3.x. Eles removeram o app.registermétodo e adicionaram o app.enginemétodo. Se você tentou a solução acima, pode acabar com o seguinte erro.

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 se livrar da mensagem de erro. Adicione a seguinte linha ao seuapp.configure function

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

Nota: você precisa instalar o ejsmecanismo de modelo

npm install -g ejs

Exemplo:

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: A solução mais simples é usar o modelo ejs como mecanismo de exibição. Lá você pode escrever HTML bruto em arquivos de visualização * .ejs.

Jak
fonte
3
Você precisa instalar ejsglobalmente?
de Drew Noakes
diz-me que não consegue encontrar o arquivo 'index.html'
MetaGuru
9

estrutura de pastas:

.
├── 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>

resultado:

Olá Mundo

KARTHIKEYAN.A
fonte
7

Se você não precisar usar o diretório views , basta mover os arquivos html para o público diretório abaixo.

e adicione esta linha ao app.configure em vez de '/ views'.

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

Para renderizar a página HTML no nó, tente o seguinte:

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

app.engine('html', require('ejs').renderFile);
  • Você precisa instalar o ejsmódulo npmcomo:

       npm install ejs --save
Trojan
fonte
Esta solução funcionou para mim. Embora eu tentei a opção estática também. Você pode explicar o mecanismo por trás disso? Obrigado!
harshad
4

Para o meu projeto eu criei esta estrutura:

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

Esse código serve index.html para /solicitações e reset.css para /css/reset.csssolicitações. Simples o suficiente, e a melhor parte é que ele adiciona automaticamente cabeçalhos de cache .

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
fonte
3

1) A melhor maneira é definir a pasta estática. No seu arquivo principal (app.js | server.js | ???):

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

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

Então você tem um arquivo estático da pasta "public":

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

2)

Você pode criar seu cache de arquivos.
Use o 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áš
fonte
não é ruim! aqui está uma demonstração completa do arquivo! https://gist.github.com/xgqfrms-GitHub/7697d5975bdffe8d474ac19ef906e906
xgqfrms
3

Com o Express 4.0.0, a única coisa que você precisa fazer é comentar duas linhas no app.js:

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

E, em seguida, solte seu arquivo estático no diretório / public. Exemplo: /public/index.html

u84six
fonte
3

Eu adicionei abaixo de 2 linhas e funcionou para mim

    app.set('view engine', 'html');
    app.engine('html', require('ejs').renderFile);
Naren Chejara
fonte
ele me dá o seguinte erro "Erro: Não é possível encontrar o módulo 'ejs' em Function.Module._resolveFilename (module.js: 338: 15) em Function.Module._load (module.js: 280: 25) em Module.require ( module.js: 364: 17) em require (module.js: 380: 17) "
Lygub Org
@LygubOrg é executado npm install ejs --saveno seu diretório de trabalho.
precisa
1
é necessário adicionar uma dependência apenas para servir um arquivo html?
perfil completo de JCarlosR
3

Tente a função res.sendFile () em rotas expressas.

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");

Leia aqui: http://codeforgeek.com/2015/01/render-html-file-expressjs/

Shaikh Shahid
fonte
3

Eu não queria depender do ejs para simplesmente entregar um arquivo HTML, então eu mesmo escrevi o pequeno 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
fonte
2

Eu estava tentando configurar um aplicativo angular com uma API RESTful expressa e cheguei nesta página várias vezes, embora não fosse útil. Aqui está o que eu achei que funcionou:

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'));
});

Em seguida, no retorno de chamada para suas rotas da API, é semelhante a: res.jsonp(users);

Sua estrutura do lado do cliente pode lidar com roteamento. Express é para servir a API.

Minha rota inicial é assim:

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
fonte
2
res.sendFile(__dirname + '/public/login.html');
himanshu yadav
fonte
2

Aqui está uma demonstração completa do servidor expresso!

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

espero que ajude para você!

// 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
fonte
1

Adicione as seguintes linhas ao seu código

  1. Substitua "jade" por "ejs" e "XYZ" (versão) por "*" no arquivo package.json

      "dependencies": {
       "ejs": "*"
      }
  2. Em seguida, no arquivo app.js, adicione o seguinte código:

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

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

  3. E lembre-se de manter todos os arquivos .HTML em visualizações

Felicidades :)

Amulya Kashyap
fonte
1

Para html simples, você não precisa de nenhum pacote ou middleware npm

basta usar isso:

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

É muito triste que seja por volta de 2020, o express ainda não adicionou uma maneira de renderizar uma página HTML sem usar o sendFilemétodo do responseobjeto. Usar sendFilenão é um problema, mas passar um argumento para ele na forma de path.join(__dirname, 'relative/path/to/file')não parece certo. Por que um usuário deve ingressar __dirnameno caminho do arquivo? Isso deve ser feito por padrão. Por que a raiz do servidor não pode ser desativada pelo diretório do projeto? Além disso, a instalação de uma dependência de modelo apenas para renderizar um arquivo HTML estático também não está correta. Não sei a maneira correta de resolver o problema, mas se eu tivesse que fornecer um HTML estático, faria 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}`);
});

O exemplo acima pressupõe que a estrutura do projeto tenha um viewsdiretório e os arquivos HTML estáticos estejam dentro dele. Por exemplo, digamos, o viewsdiretório tem dois arquivos HTML nomeados index.htmle about.html, para acessá-los, podemos visitar: localhost:8153/index.htmlou apenas localhost:8153/para carregar a index.htmlpágina e localhost:8153/about.htmlcarregar o arquivo about.html. Podemos usar uma abordagem semelhante para servir um aplicativo react / angular armazenando os artefatos no viewsdiretório ou apenas usando o dist/<project-name>diretório padrão e configurando-o no servidor js da seguinte maneira:

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

Eu queria permitir que solicitações "/" fossem tratadas por uma rota Express, onde anteriormente elas eram tratadas pelo middleware estático. Isso me permitiria renderizar a versão regular de index.html ou uma versão que carregasse JS e CSS concatenados + minificados, dependendo das configurações do aplicativo. Inspirado na resposta de Andrew Homeyer , decidi arrastar meus arquivos HTML - não modificados - para uma pasta de visualizações, configurar o Express assim

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

E criou um manipulador de rota assim

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

Isso funcionou muito bem.

K. Francis
fonte
0

No server.js, inclua

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
fonte
0

Se você está tentando veicular um arquivo HTML que JÁ possui todo o seu conteúdo, ele não precisa ser 'renderizado', só precisa ser 'veiculado'. A renderização ocorre quando o servidor atualiza ou injeta conteúdo antes que a página seja enviada ao navegador e requer dependências adicionais, como ejs, como mostram as outras respostas.

Se você simplesmente deseja direcionar o navegador para um arquivo com base em sua solicitação, use res.sendFile () como este:

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));

Dessa forma, você não precisa de dependências adicionais além do express. Se você deseja apenas que o servidor envie seus arquivos html já criados, a descrição acima é uma maneira muito leve de fazer isso.

aleph_one
fonte
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');
})

Coloque seu arquivo index.html na pasta pública

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

Agora execute o seguinte código no seu terminal

nó index.js

Ahmad Sharif
fonte
-1

Eu costumo usar isso

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

Apenas tome cuidado, pois isso compartilhará qualquer coisa no diretório / web.

Espero que ajude

DiogoNeves
fonte
-2

se você estiver usando o framework expresso para node.js

instalar npm ejs

adicione o arquivo de configuração

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)

;

renderize a página do módulo de exportações form.js com o arquivo html no diretório views com a extensão do nome do arquivo ejs como form.html.ejs

então crie o form.js

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

aruneshtechno
fonte
Que bagunça é essa?
Vighnesh Raut