Rendre la vue HTML de base?


279

J'ai une application node.js de base que j'essaie de décoller en utilisant le framework Express. J'ai un viewsdossier où j'ai un index.htmlfichier. Mais je reçois l'erreur suivante lors du chargement du navigateur Web.

Erreur: impossible de trouver le module 'html'

Voici mon code.

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

Qu'est-ce que j'oublie ici?

Réponses:


299

Vous pouvez avoir jade inclure une page HTML simple:

dans views / index.jade

include plain.html

dans vues / plain.html

<!DOCTYPE html>
...

et app.js peut toujours rendre le jade:

res.render(index)

1
Juste pour noter que ce que je voulais, c'était ne servir qu'un seul fichier .html car mon application n'était qu'une seule page;)
diosney

1
Pouvons-nous inclure plusieurs pages HTML / JS avec cette méthode?
user3398326

6
ne devriez-vous pas être en mesure de rendre cette page html sans modèle jade uniquement pour les tests initiaux d'express?
PositiveGuy

1
Faut-il donc créer un modèle jade pour chacun de nos fichiers HTML?
Chris - Jr

4
Plus un hack plutôt qu'une solution.
Ozil

226

Beaucoup de ces réponses sont obsolètes.

En utilisant express 3.0.0 et 3.1.0, les travaux suivants:

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

Voir les commentaires ci-dessous pour une syntaxe alternative et des mises en garde pour express 3.4+:

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

Ensuite, vous pouvez faire quelque chose comme:

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

Cela suppose que vous avez vos vues dans le viewssous - dossier et que vous avez installé le ejsmodule de noeud. Sinon, exécutez ce qui suit sur une console Node:

npm install ejs --save

@MichaelDausmann, cheers, j'ai inclus cette information dans la réponse.
Drew Noakes

pourquoi le res.render nécessite-t-il l'extension .html dans ce cas mais pas dans le cas par défaut avec jade. avec le code passe-partout, il appelle simplement res.render ('index', {title: 'Express'}); mais ici, c'est: res.render ('about.html');
Transcendance

6
Avec Express 3.4.2: app.set («moteur de vue», «ejs»);
roland

3
Vous devez utiliser la commande 'npm install ejs --save' pour mettre à jour votre package.json
Tom Teman

8
pourquoi avez-vous besoin d'ejs?
PositiveGuy

71

Depuis le Guide Express.js: Afficher le rendu

Les noms de fichiers de vue prennent la forme Express.ENGINE, où ENGINEest le nom du module qui sera requis. Par exemple, la vue layout.ejsindiquera au système de vuerequire('ejs') , le module en cours de chargement doit exporter la méthodeexports.render(str, options) pour se conformer à Express, mais app.register()peut être utilisé pour mapper les moteurs aux extensions de fichier, de sorte que, par exemple, foo.htmlpuisse être rendu par jade.

Donc, soit vous créez votre propre rendu simple, soit vous utilisez simplement du jade:

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

Plus au sujet app.register.

Notez que dans Express 3, cette méthode est renommée app.engine


57
Remarque - app.register a été renommé app.engine dans Express 3.
Spongeboy

8
Voir la réponse d'Andrew Homeyer. C'est la vraie réponse.
David Betz

7
D'après une autre réponse, pour Express 4, j'ai fini par utiliserapp.engine('.html', require('ejs').renderFile);
CrazyPyro

Dans express 4, vous pouvez également utiliser: app.set ('view engine', 'jade');
Daniel Huang

48

Vous pouvez également lire le fichier HTML et l'envoyer:

app.get('/', (req, res) => {
    fs.readFile(__dirname + '/public/index.html', 'utf8', (err, text) => {
        res.send(text);
    });
});

23
cette solution est mauvaise car pas de mise en cache des fichiers; il est lu pour chaque demande.
Marcel Falliere

2
il est potentiellement assez facile de le mettre en cache manuellement. Il suffit de stocker le fichier lu dans une variable et de ne relire que si cette variable est vide. Vous pouvez également utiliser un objet JS et stocker divers fichiers dans diverses variables, avec des horodatages. Bien sûr, cela demande plus de travail que la plupart des gens, mais c'est bien avec les nouveaux utilisateurs de node. C'est facile à comprendre
Naman Goel

5
Oui. Cela bat tout le point des architectures rationalisées orientées conventions (comme MVC).
David Betz

@MarcelFalliere Vous supposez qu'il veut mettre en cache le fichier ou qu'il ne veut pas utiliser une solution de mise en cache personnalisée. Merci keegan3d pour la réponse.
Benny

@MarcelFalliere Alors, quelle est la bonne solution? Je vois d'autres réponses qui nécessitent de nouvelles dépendances. Est-ce nécessaire uniquement pour servir des fichiers html?
JCarlosR

45

essaye ça. ça marche pour moi.

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

2
eu des problèmes avec la configuration exacte ci-dessus, j'ai donc supprimé le point de ".html" et ajouté ceci: app.set ('view engine', 'html'); app.set ('views', __dirname + '/ views'); pour un rendu parfait
Bijou Trouvaille

8
C'est un peu bizarre ... vous devez servir du HTML en tant que fichiers statiques. Cela vous donne également l'avantage d'une meilleure mise en cache. La création d'un "compilateur html" personnalisé semble incorrecte. Si vous devez envoyer un fichier à partir d'une route (ce que vous avez très rarement à faire), il suffit de le lire et de l'envoyer. Sinon, redirigez simplement vers le html statique.
enyo

2
@Enyo, ce commentaire semble étrange, étant donné QUE COMMENT FAIRE ce que vous dites devrait être fait, c'est LA QUESTION QUI EST POSÉE, et votre réponse est de le faire. Comment servir un html statique avec mise en cache?
Kyeotic

3
Je vois une erreur sur app.register. Peut-être qu'il est obsolète dans express 3.0.0.rc3? TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
Drew Noakes

1
@enyo, vous avez manqué le point de l'architecture steamline. Lorsque le modèle est contrôleur / vue (ou / processeur / vue, quelle que soit votre architecture spécifique), vous ne pouvez pas vous en écarter avec le modèle obsolète d'extensions. Vous devez traiter votre HTML comme du contenu rendu comme tout le reste. Gardez-le SEC, mec.
David Betz

22
app.get('/', function (req, res) {
res.sendfile(__dirname + '/public/index.html');
});

5
sendfile n'est pas un cache en mode production, ce n'est donc pas une bonne solution.
Teo Choong Ping

1
@SeymourCakes Veuillez me corriger si je me trompe, mais je pense que sendFile prend désormais en charge la mise en cache: devdocs.io/express/index#res.sendFile
KhoPhi

19

Si vous utilisez express@~3.0.0, changez la ligne ci-dessous à partir de votre exemple:

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

à quelque chose comme ça:

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

Je l'ai fait comme décrit sur la page api express et cela fonctionne comme un charme. Avec cette configuration, vous n'avez pas à écrire de code supplémentaire, il devient donc assez facile à utiliser pour votre microproduction ou vos tests.

Code complet ci-dessous:

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

1
Pourquoi répétez-vous app.use(express.static(__dirname + '/public'));après avoir démarré le serveur avec app.listen?
fatuhoku

2
quelle est la différence entre servir la page html en statique et simplement la charger non statique avec express?
PositiveGuy

14

J'ai également rencontré le même problème dans express 3.Xet node 0.6.16. La solution donnée ci-dessus ne fonctionnera pas pour la dernière version express 3.x. Ils ont supprimé la app.registerméthode et ajouté la app.engineméthode. Si vous avez essayé la solution ci-dessus, vous pouvez vous retrouver avec l'erreur suivante.

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)

Pour se débarrasser du message d'erreur. Ajoutez la ligne suivante à votreapp.configure function

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

Remarque: vous devez installer le ejsmoteur de modèle

npm install -g ejs

Exemple:

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

Remarque: La solution la plus simple consiste à utiliser le modèle ejs comme moteur de vue. Là, vous pouvez écrire du HTML brut dans les fichiers de vue * .ejs.


3
Devez-vous installer ejsglobalement?
Drew Noakes

c'est me dire qu'il ne trouve pas le fichier 'index.html'
MetaGuru

9

structure des dossiers:

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

production:

Bonjour le monde


7

Si vous n'avez pas besoin d'utiliser le répertoire des vues , déplacez simplement les fichiers html vers le répertoire public ci-dessous.

puis ajoutez cette ligne dans app.configure au lieu de '/ views'.

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

5

Pour afficher la page Html dans le nœud, essayez ce qui suit,

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

app.engine('html', require('ejs').renderFile);
  • Vous devez installer le ejsmodule npmcomme:

       npm install ejs --save

Cette solution a fonctionné pour moi. Bien que j'aie aussi essayé l'option statique. Pouvez-vous expliquer le mécanisme derrière cela. Merci!
harshad

4

Pour mon projet, j'ai créé cette structure:

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

Ce code sert index.html pour les /demandes et reset.css pour les /css/reset.cssdemandes. Assez simple, et la meilleure partie est qu'il ajoute automatiquement des en-têtes 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);

3

1) La meilleure façon est de définir un dossier statique. Dans votre fichier principal (app.js | server.js | ???):

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

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

Ensuite, vous avez obtenu un fichier statique du dossier "public":

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

2)

Vous pouvez créer votre cache de fichiers.
Utilisez la méthode 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"] );                                
};);


3

Avec Express 4.0.0, la seule chose que vous avez à faire est de commenter 2 lignes dans app.js:

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

Et puis déposez votre fichier statique dans le répertoire / public. Exemple: /public/index.html


3

J'ai ajouté en dessous de 2 lignes et ça marche pour moi

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

il me donne l'erreur suivante "Erreur: Impossible de trouver le module 'ejs' à Function.Module._resolveFilename (module.js: 338: 15) à Function.Module._load (module.js: 280: 25) à Module.require ( module.js: 364: 17) at require (module.js: 380: 17) "
Lygub Org

@LygubOrg s'exécute npm install ejs --savedans votre répertoire de travail.
A1rPun

1
est-il nécessaire d'ajouter une dépendance uniquement pour servir un fichier html?
JCarlosR

3

Essayez la fonction res.sendFile () dans les itinéraires 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");

Lisez ici: http://codeforgeek.com/2015/01/render-html-file-expressjs/


3

Je ne voulais pas dépendre d'ejs pour livrer simplement un fichier HTML, j'ai donc simplement écrit le petit rendu moi-même:

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

2

J'essayais de configurer une application angulaire avec une API RESTful express et j'ai atterri sur cette page plusieurs fois, mais cela n'a pas été utile. Voici ce que j'ai trouvé qui a fonctionné:

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

Ensuite, dans le rappel de vos itinéraires API, ressemble à: res.jsonp(users);

Votre infrastructure côté client peut gérer le routage. Express sert à servir l'API.

Mon itinéraire d'origine ressemble à ceci:

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


2

Voici une démo complète du serveur express!

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

j'espère que cela vous aidera!

// 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}!
    `);
});


1

Ajoutez les lignes suivantes à votre code

  1. Remplacez "jade" par "ejs" & "XYZ" (version) par "*" dans le fichier package.json

      "dependencies": {
       "ejs": "*"
      }
  2. Ensuite, dans votre fichier app.js, ajoutez le code suivant:

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

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

  3. Et n'oubliez pas de conserver tous les fichiers .HTML dans le dossier des vues

À votre santé :)


1

Pour du HTML simple, vous n'avez besoin d'aucun paquetage npm ou middleware

utilisez simplement ceci:

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

1

Il est très triste qu'il soit environ 2020, encore express n'a pas ajouté un moyen de rendre une page HTML sans utiliser la sendFileméthode de l' responseobjet. L'utilisation sendFilen'est pas un problème, mais lui transmettre un argument sous la forme de path.join(__dirname, 'relative/path/to/file')ne se sent pas bien. Pourquoi un utilisateur devrait-il rejoindre __dirnamele chemin du fichier? Cela devrait être fait par défaut. Pourquoi la racine du serveur ne peut-elle pas être par défaut le répertoire du projet? De plus, l'installation d'une dépendance de modèle juste pour rendre un fichier HTML statique n'est pas correcte. Je ne connais pas la bonne façon de résoudre le problème, mais si je devais servir un HTML statique, je ferais quelque chose comme:

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

L'exemple ci-dessus suppose que la structure du projet possède un viewsrépertoire et que les fichiers HTML statiques s'y trouvent. Par exemple, disons, le viewsrépertoire a deux fichiers HTML nommés index.htmlet about.html, pour y accéder, nous pouvons visiter: localhost:8153/index.htmlou simplement localhost:8153/pour charger la index.htmlpage et localhost:8153/about.htmlpour charger le about.html. Nous pouvons utiliser une approche similaire pour servir une application react / angular en stockant les artefacts dans le viewsrépertoire ou simplement en utilisant le dist/<project-name>répertoire par défaut et en le configurant dans le serveur js comme suit:

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

0

Je voulais permettre que les requêtes "/" soient gérées par une route Express alors qu'auparavant elles étaient gérées par le middleware statique. Cela me permettrait de rendre la version régulière de index.html ou une version qui chargeait JS et CSS concaténés + minifiés, selon les paramètres de l'application. Inspiré par la réponse d'Andrew Homeyer , j'ai décidé de faire glisser mes fichiers HTML - non modifiés - dans un dossier de vues, de configurer Express comme ça

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

Et créé un gestionnaire d'itinéraire comme ça

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

Cela a plutôt bien fonctionné.


0

Dans server.js, veuillez inclure

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

0

Si vous essayez de servir un fichier HTML qui contient DÉJÀ tout son contenu, il n'a pas besoin d'être «rendu», il doit simplement être «servi». Le rendu est lorsque vous avez la mise à jour du serveur ou injectez du contenu avant que la page ne soit envoyée au navigateur, et cela nécessite des dépendances supplémentaires comme ejs, comme les autres réponses le montrent.

Si vous souhaitez simplement diriger le navigateur vers un fichier en fonction de leur demande, vous devez utiliser res.sendFile () comme ceci:

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 cette façon, vous n'avez pas besoin de dépendances supplémentaires en plus d'exprimer. Si vous voulez simplement que le serveur envoie vos fichiers html déjà créés, ce qui précède est un moyen très léger de le faire.


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

Mettez votre fichier index.html dans un dossier public

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

Maintenant, exécutez le code suivant dans votre terminal

node index.js


0

Express 4.x

Envoyer des fichiers .html, pas de moteur de modèle ...

//...
// Node modules
const path = require('path')
//...
// Set path to views directory
app.set('views', path.join(__dirname, 'views'))
/**
 * App routes
 */
app.get('/', (req, res) => {
  res.sendFile('index.html', { root: app.get('views') })
})
//...
.
├── node_modules

├── views
   ├──index.html
└── app.js

-1

J'utilise habituellement ceci

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

Faites juste attention car cela partagera n'importe quoi dans le répertoire / web.

J'espère que ça aide


-2

si vous utilisez un framework express pour node.js

installer npm ejs

puis ajoutez le fichier de configuration

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)

;

afficher la page du module d'export form.js ont le fichier html dans le répertoire des vues avec l'extension du nom de fichier ejs comme form.html.ejs

puis créez le form.js

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


Quel est ce gâchis?
Vighnesh Raut
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.