Czy renderujesz podstawowy widok HTML?


279

Mam podstawową aplikację node.js, którą próbuję uruchomić z poziomu frameworka Express. Mam viewsfolder, w którym mam index.htmlplik. Ale podczas ładowania przeglądarki pojawia się następujący błąd.

Błąd: nie można znaleźć modułu „HTML”

Poniżej znajduje się mój kod.

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

Czego tu brakuje?

Odpowiedzi:


298

Jadeit może zawierać zwykłą stronę HTML:

w views / index.jade

include plain.html

w views / plain.html

<!DOCTYPE html>
...

i app.js nadal mogą po prostu renderować jade:

res.render(index)

1
Wystarczy zauważyć, że chciałem tylko jeden plik .html, ponieważ moja aplikacja była jednostronicowa;)
diosney

1
Czy tą metodą możemy zawrzeć wiele stron HTML / JS?
user3398326

6
nie powinieneś być w stanie renderować tej strony HTML bez szablonu Jade tylko do początkowego testowania Express?
PositiveGuy

1
Czy więc musimy stworzyć szablon jade dla każdego z naszych plików HTML?
Chris - Jr

4
Bardziej hack niż rozwiązanie.
Ozil,

226

Wiele z tych odpowiedzi jest nieaktualnych.

Przy użyciu ekspresowych wersji 3.0.0 i 3.1.0 działa:

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

Zobacz komentarze poniżej dotyczące alternatywnej składni i zastrzeżeń dla ekspresu 3.4+:

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

Następnie możesz zrobić coś takiego:

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

Zakłada się, że masz swoje widoki w viewspodfolderze i że zainstalowałeś ejsmoduł węzła. Jeśli nie, uruchom następujące polecenie na konsoli węzła:

npm install ejs --save

@MichaelDausmann, na zdrowie, dołączyłem te informacje do odpowiedzi.
Drew Noakes

dlaczego res.render wymaga rozszerzenia .html w tym przypadku, ale nie w domyślnym przypadku z jadesem. z kodem typu kocioł wywołuje po prostu res.render ('index', {title: 'Express'}); ale tutaj jest: res.render ('about.html');
Transcendencja

6
W Express 3.4.2: zestaw aplikacji („przeglądaj silnik”, „ejs”);
roland

3
Należy użyć polecenia „npm install ejs --save”, aby zaktualizować pakiet.json
Tom Teman

8
dlaczego potrzebujesz ejs?
PositiveGuy

71

Z Przewodnika Express.js: Wyświetl renderowanie

Wyświetl nazwy plików mają postać Express.ENGINE, gdzie ENGINEjest nazwa modułu, który będzie wymagany. Na przykład widok layout.ejspowie systemowi wyświetlaniarequire('ejs') , że ładowany moduł musi wyeksportować metodę wexports.render(str, options) celu zachowania zgodności z Express, jednak app.register()można go użyć do mapowania silników na rozszerzenia plików, aby na przykład foo.htmlmożna było renderować za pomocą jade.

Więc albo stwórz swój własny prosty renderer, albo po prostu użyjesz jadeitu:

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

Więcej o app.register.

Należy pamiętać, że w Express 3 ta metoda została zmieniona app.engine


57
Uwaga: nazwa app.register została przemianowana na app.engine w Express 3.
Spongeboy

8
Zobacz odpowiedź Andrew Homeyera. To jest rzeczywista odpowiedź.
David Betz

7
Z innej odpowiedzi, w przypadku Express 4 skończyłem używaćapp.engine('.html', require('ejs').renderFile);
CrazyPyro

W Express 4 możesz także użyć: app.set („view engine”, „jade”);
Daniel Huang,

48

Możesz także przeczytać plik HTML i wysłać go:

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

23
to rozwiązanie jest złe, ponieważ nie buforuje plików; jest czytany dla każdego żądania.
Marcel Falliere

2
potencjalnie dość łatwo można go ręcznie buforować. Po prostu zapisz odczytany plik jako zmienną i czytaj tylko ponownie, jeśli zmienna jest pusta. Możesz także użyć obiektu JS i przechowywać różne pliki w różnych zmiennych wraz ze znacznikami czasu. Jasne, że to więcej pracy niż większość ludzi, ale dobrze jest z nowymi użytkownikami węzłów. Łatwo to zrozumieć
Naman Goel

5
Yikes. To pokonuje cały punkt zorientowanych na konwencje, usprawnionych architektur (takich jak MVC).
David Betz

@MarcelFalliere Zakładasz, że chce buforować plik lub że nie chce używać niestandardowego rozwiązania buforowania. Dziękuję keegan3d za odpowiedź.
Benny,

@MarcelFalliere Zatem, jakie jest właściwe rozwiązanie? Widzę inne odpowiedzi, które wymagają nowych zależności. Czy jest to konieczne tylko do obsługi plików HTML?
JCarlosR

45

Spróbuj tego. mi to pasuje.

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
miałem problem z dokładną konfiguracją powyżej, więc usunąłem kropkę z „.html” i dodałem to: app.set („view engine”, „html”); app.set ('views', __dirname + '/ views'); dla idealnego renderowania
Bijou Trouvaille

8
To trochę dziwne ... powinieneś podawać HTML jako pliki statyczne. Daje to również korzyść z lepszego buforowania. Tworzenie niestandardowego „kompilatora HTML” wydaje się nieprawidłowe. Jeśli chcesz wysłać plik z trasy (co bardzo rzadko musisz to robić), po prostu przeczytaj go i wyślij. W przeciwnym razie po prostu przekieruj do statycznego HTML.
enyo

2
@Enyo ten komentarz wydaje się dziwny, biorąc pod uwagę, W JAKI SPOSÓB zrobić to, o czym mówisz, że należy zrobić, PYTANIE JEST PYTANE, a twoją odpowiedzią jest po prostu to zrobić. Jak podajesz statyczny HTML z buforowaniem?
Kyeotic

3
Widzę błąd włączony app.register. Być może został on przestarzały w Express 3.0.0.rc3? TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
Drew Noakes

1
@enyo, przegapiłeś punkt architektury z parą. Kiedy wzorcem jest kontroler / widok (lub / procesor / widok, bez względu na to, jaka jest twoja konkretna architektura), nie możesz odejść od tego w przypadku przestarzałego modelu rozszerzeń. Musisz traktować swój HTML jako renderowaną treść jak wszystko inne. Trzymaj to SUCHO, stary.
David Betz

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

5
sendfile nie jest pamięcią podręczną w trybie produkcyjnym, więc nie jest to dobre rozwiązanie.
Teo Choong Ping

1
@SeymourCakes Prosimy o poprawienie mnie, jeśli się mylę, ale myślę, że sendFile obsługuje teraz buforowanie: devdocs.io/express/index#res.sendFile
KhoPhi

19

Jeśli używasz express@~3.0.0, zmień poniższy wiersz z przykładu:

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

do czegoś takiego:

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

Zrobiłem to tak, jak opisano na stronie ekspresowego interfejsu API i działa jak urok. Dzięki tej konfiguracji nie musisz pisać dodatkowego kodu, dzięki czemu korzystanie z niego do mikrodukcji lub testowania staje się łatwe.

Pełny kod wymieniony poniżej:

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
Dlaczego powtarzasz app.use(express.static(__dirname + '/public'));po uruchomieniu serwera app.listen?
fatuhoku,

2
Jaka jest różnica w wyświetlaniu strony HTML jako statycznej, a po prostu ładowaniu jej niestatycznej za pomocą ekspresu?
PositiveGuy

14

Ten sam problem spotkałem również w express 3.Xi node 0.6.16. Powyższe rozwiązanie nie będzie działać w najnowszej wersji express 3.x. Usunęli app.registermetodę i dodali app.enginemetodę. Jeśli wypróbowałeś powyższe rozwiązanie, może wystąpić następujący błąd.

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)

Aby pozbyć się komunikatu o błędzie. Dodaj następujący wiersz do swojegoapp.configure function

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

Uwaga: musisz zainstalować ejssilnik szablonów

npm install -g ejs

Przykład:

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

Uwaga: najprostszym rozwiązaniem jest użycie szablonu ejs jako silnika przeglądania. Tam możesz pisać nieprzetworzony HTML w plikach przeglądania * .ejs.


3
Czy musisz instalować ejsglobalnie?
Drew Noakes,

mówi mi, że nie może znaleźć pliku „index.html”
MetaGuru,

9

struktura folderów:

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

wynik:

Witaj świecie


7

Jeśli nie musisz korzystać z katalogu views , po prostu przenieś pliki HTML do katalogu publicznego poniżej.

a następnie dodaj tę linię do app.configure zamiast „/ views”.

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

5

Aby wyświetlić stronę HTML w węźle, spróbuj wykonać następujące czynności:

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

app.engine('html', require('ejs').renderFile);
  • Musisz zainstalować ejsmoduł poprzez npm:

       npm install ejs --save

To rozwiązanie działało dla mnie. Chociaż próbowałem też opcji statycznej. Czy możesz wyjaśnić mechanizm za tym. Dzięki!
harshad

4

Dla mojego projektu stworzyłem następującą strukturę:

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

Ten kod obsługuje index.html dla /żądań i reset.css dla /css/reset.cssżądań. To dość proste, a najlepsze jest to, że automatycznie dodaje nagłówki pamięci podręcznej .

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) Najlepszym sposobem jest ustawienie folderu statycznego. W głównym pliku (app.js | server.js | ???):

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

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

Następnie masz plik statyczny z folderu „publicznego”:

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

2)

Możesz utworzyć pamięć podręczną plików.
Użyj metody 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"] );                                
};);

nie jest zły! tutaj jest pełna wersja demonstracyjna pliku! https://gist.github.com/xgqfrms-GitHub/7697d5975bdffe8d474ac19ef906e906
xgqfrms

3

W Express 4.0.0 jedyne, co musisz zrobić, to skomentować 2 wiersze w app.js:

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

A następnie upuść plik statyczny do katalogu / public. Przykład: /public/index.html


3

Dodałem poniżej 2 linii i to działa dla mnie

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

pojawia się następujący błąd „Błąd: Nie można znaleźć modułu„ ejs ”w Function.Module._resolveFilename (module.js: 338: 15) w Function.Module._load (module.js: 280: 25) w Module.require ( module.js: 364: 17) na żądanie (module.js: 380: 17) "
Lygub Org

@LygubOrg uruchom npm install ejs --savew swoim katalogu roboczym.
A1rPun

1
czy konieczne jest dodanie zależności tylko do obsługi pliku HTML?
JCarlosR

3

Wypróbuj funkcję res.sendFile () na trasach ekspresowych.

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

Przeczytaj tutaj: http://codeforgeek.com/2015/01/render-html-file-expressjs/


3

Nie chciałem polegać na ejs po prostu dostarczając plik HTML, więc po prostu sam napisałem mały renderer:

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

Próbowałem skonfigurować aplikację kątową z ekspresowym interfejsem API RESTful i wylądowałem na tej stronie wiele razy, ale nie było to pomocne. Oto, co znalazłem, które zadziałało:

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

Następnie w wywołaniu zwrotnym dla twoich tras API wygląda następująco: res.jsonp(users);

Struktura po stronie klienta może obsługiwać routing. Express służy do obsługi interfejsu API.

Moja domowa trasa wygląda następująco:

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

Oto pełna wersja demonstracyjna serwera ekspresowego!

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

mam nadzieję, że ci to pomoże!

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

Dodaj następujące linie do swojego kodu

  1. Zamień „jade” na „ejs” i „XYZ” (wersja) na „*” w pliku package.json

      "dependencies": {
       "ejs": "*"
      }
  2. Następnie w pliku app.js dodaj następujący kod:

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

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

  3. I pamiętaj Zachowaj wszystkie pliki .HTML w folderze widoków

Twoje zdrowie :)


1

W przypadku zwykłego html nie potrzebujesz pakietu npm ani oprogramowania pośredniego

po prostu użyj tego:

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

1

To bardzo smutne, że około 2020 roku wciąż express nie dodał sposobu renderowania strony HTML bez użycia sendFilemetody responseobiektu. Używanie sendFilenie jest problemem, ale przekazywanie argumentów w formie path.join(__dirname, 'relative/path/to/file')nie wydaje się właściwe. Dlaczego użytkownik powinien dołączyć __dirnamedo ścieżki pliku? Powinno to być zrobione domyślnie. Dlaczego katalog główny serwera nie może być przez defalutowanie katalogu projektu? Ponadto instalacja zależności szablonów tylko w celu renderowania statycznego pliku HTML jest znowu niepoprawna. Nie znam właściwego sposobu rozwiązania tego problemu, ale gdybym musiał podać statyczny kod HTML, zrobiłbym coś takiego:

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

Powyższy przykład zakłada, że ​​struktura projektu ma viewskatalog i znajdują się w nim statyczne pliki HTML. Na przykład, powiedzmy, viewskatalog zawiera dwa pliki HTML nazwanych index.htmli about.html, następnie, aby uzyskać do nich dostęp, możemy odwiedzić: localhost:8153/index.htmlalbo po prostu localhost:8153/załadować index.htmlstronę i localhost:8153/about.htmlaby załadować about.html. Możemy zastosować podobne podejście do obsługi aplikacji reagującej / kątowej, przechowując artefakty w viewskatalogu lub po prostu używając dist/<project-name>katalogu domyślnego i konfigurując go w serwerze js w następujący sposób:

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

0

Chciałem zezwolić, aby żądania do „/” były obsługiwane przez trasę ekspresową, gdzie wcześniej były obsługiwane przez oprogramowanie pośrednie statyki. Pozwoliłoby mi to renderować zwykłą wersję pliku index.html lub wersję, która załadowała konkatenację + zminimalizowany JS i CSS, w zależności od ustawień aplikacji. Zainspirowany odpowiedzią Andrew Homeyera postanowiłem przeciągnąć moje pliki HTML - niezmodyfikowane - do folderu widoków, tak skonfigurować Express

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

I tak utworzył moduł obsługi trasy

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

To działało całkiem dobrze.


0

Dołącz do server.js

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

Jeśli próbujesz podać plik HTML, który JUŻ zawiera w sobie całą jego zawartość, nie trzeba go „renderować”, wystarczy go „doręczyć”. Renderowanie ma miejsce, gdy masz aktualizację serwera lub wstrzykujesz zawartość przed wysłaniem strony do przeglądarki i wymaga ona dodatkowych zależności, takich jak ejs, jak pokazują inne odpowiedzi.

Jeśli chcesz po prostu skierować przeglądarkę do pliku na podstawie ich żądania, powinieneś użyć res.sendFile () w następujący sposób:

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

W ten sposób nie potrzebujesz dodatkowych zależności oprócz express. Jeśli chcesz, aby serwer wysyłał już utworzone pliki HTML, powyższe jest bardzo lekkim sposobem.


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

Umieść plik index.html w folderze publicznym

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

Teraz uruchom następujący kod w swoim terminalu

węzeł index.js


-1

Zwykle tego używam

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

Bądź ostrożny, ponieważ udostępni to wszystko w katalogu / web.

Mam nadzieję, że to pomoże


-2

jeśli używasz Express Framework do node.js

zainstaluj npm ejs

następnie dodaj plik konfiguracyjny

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)

;

wyrenderuj stronę z modułu eksportu form.js plik html w katalogu widoków z rozszerzeniem nazwy pliku ejs jako form.html.ejs

następnie utwórz plik form.js

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


Co to za bałagan?
Vighnesh Raut
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.