Визуализировать базовый вид HTML?


279

У меня есть базовое приложение node.js, которое я пытаюсь использовать с помощью Express Framework. У меня есть viewsпапка, где у меня есть index.htmlфайл. Но я получаю следующую ошибку при загрузке веб-браузера.

Ошибка: не удается найти модуль "HTML"

Ниже мой код.

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

Что мне здесь не хватает?

Ответы:


299

Вы можете включить в Jade обычную HTML-страницу:

в views / index.jade

include plain.html

в views / plain.html

<!DOCTYPE html>
...

и app.js все еще может просто визуализировать Jade:

res.render(index)

1
Просто хочу отметить, что мне нужно было предоставить только один файл .html, потому что мое приложение было одной страницей;)
diosney

1
Можем ли мы включить несколько страниц HTML / JS с этим методом?
user3398326

6
разве вы не сможете рендерить эту HTML-страницу без нефритового шаблона только для первоначального тестирования экспресс?
PositiveGuy

1
Так нужно ли нам создавать шаблон Jade для каждого из наших HTML-файлов?
Крис - младший

4
Больше взломать, чем решение.
Озил

226

Многие из этих ответов устарели.

Используя экспресс 3.0.0 и 3.1.0, работает следующее:

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

Смотрите комментарии ниже для альтернативного синтаксиса и предостережений для Express 3.4+:

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

Тогда вы можете сделать что-то вроде:

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

Это предполагает, что у вас есть ваши представления в viewsподпапке, и что вы установили ejsмодуль узла. Если нет, запустите следующее на консоли Node:

npm install ejs --save

@MichaelDausmann, ура, я включил эту информацию в ответ.
Дрю Ноакс

почему res.render требует расширения .html в этом случае, но не в случае по умолчанию с jade. с помощью стандартного кода он просто вызывает res.render ('index', {title: 'Express'}); но здесь это: res.render ('about.html');
Превосходство

6
В Express 3.4.2: app.set («просмотр движка», «ejs»);
Роланд

3
Вы должны использовать команду 'npm install ejs --save' для обновления вашего package.json
Том Теман

8
зачем тебе ejs?
PositiveGuy

71

Из руководства Express.js: Просмотр рендеринга

Просмотр имен файлов осуществляется в форме Express.ENGINE, где ENGINEуказано имя модуля, который потребуется. Например, представление layout.ejsсообщит системе представленияrequire('ejs') , что загружаемый модуль должен экспортировать методexports.render(str, options) для соответствия Express, однако app.register()его можно использовать для привязки механизмов к расширениям файлов, что, например, foo.htmlможет быть визуализировано с помощью jade.

Так что либо вы создаете свой собственный простой рендерер, либо просто используете Jade:

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

Подробнее о app.register.

Обратите внимание, что в Express 3 этот метод переименован app.engine


57
Примечание - app.register был переименован в app.engine в Express 3.
Губка

8
Смотрите ответ от Эндрю Хомейера. Это фактический ответ.
Дэвид Бетц

7
Из какого-то другого ответа, для Express 4 я в конечном итоге использовалapp.engine('.html', require('ejs').renderFile);
CrazyPyro

В Express 4 вы также можете использовать: app.set ('view engine', 'jade');
Даниэль Хуан

48

Вы также можете прочитать файл HTML и отправить его:

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

23
это решение плохо, потому что нет кэширования файлов; это читается для каждого запроса.
Марсель Фальер

2
его потенциально довольно легко кэшировать вручную. Просто сохраните прочитанный файл как переменную и читайте снова, только если эта переменная пуста. Вы также можете использовать объект JS и хранить различные файлы в различных переменных с временными метками. Конечно, это больше работы, чем большинство людей, но это хорошо с людьми, плохо знакомыми с узлом. Это легко понять
Наман Гоэль

5
Хлоп. Это побеждает весь смысл условно-ориентированных, обтекаемых архитектур (таких как MVC).
Дэвид Бетц

@MarcelFalliere Вы предполагаете, что он хочет кэшировать файл или что он не хочет использовать пользовательское решение для кэширования. Спасибо keegan3d за ответ.
Бенни

@MarcelFalliere Тогда, каково правильное решение? Я вижу другие ответы, которые требуют новых зависимостей. Это необходимо только для обслуживания файлов HTML?
JCarlosR

45

попробуй это. меня устраивает.

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
были проблемы с точной конфигурацией, описанной выше, поэтому я удалил точку из «.html» и добавил это: app.set ('view engine', 'html'); app.set ('views', __dirname + '/ views'); для идеального рендера
Bijou Trouvaille

8
Это немного странно ... вы должны использовать html как статические файлы. Это также дает вам преимущество лучшего кэширования. Создание собственного "HTML-компилятора" кажется неправильным. Если вам нужно отправить файл из маршрута (что вам очень редко требуется), просто прочитайте и отправьте его. В противном случае просто перенаправить на статический HTML.
enyo

2
@Enyo, этот комментарий кажется странным, учитывая, КАК сделать то, что вы говорите, должно быть сделано, ВОПРОС ЗАДАВАЕТСЯ, а ваш ответ - просто сделать это. Как вы обслуживаете статический HTML с кэшированием?
Kyeotic

3
Я вижу ошибку на app.register. Возможно, это не рекомендуется в Express 3.0.0.rc3? TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
Дрю Ноакс

1
@enyo, ты упустил из виду запутанную архитектуру. Когда паттерном является контроллер / представление (или / процессор / представление, какой бы ни была ваша конкретная архитектура), вы не можете отклониться от этого с помощью устаревшей модели расширений. Вы должны относиться к своему HTML как к отображаемому контенту, как ко всему прочему. Держи это сухим, чувак.
Дэвид Бец

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

5
sendfile не является кешем в производственном режиме, поэтому это не очень хорошее решение.
Тео Чунг Пинг

1
@SeymourCakes Пожалуйста, поправьте меня, если я не прав, но я думаю, что sendFile теперь поддерживает кеширование: devdocs.io/express/index#res.sendFile
KhoPhi

19

Если вы используете express@~3.0.0, измените строку ниже из вашего примера:

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

что-то вроде этого:

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

Я сделал это, как описано на странице экспресс-API, и это работает как шарм. При такой настройке вам не нужно писать дополнительный код, поэтому его становится достаточно просто использовать для микропроизводства или тестирования.

Полный код указан ниже:

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
Почему вы повторяете app.use(express.static(__dirname + '/public'));после запуска сервера с app.listen?
фатухоку

2
Какова разница в обслуживании html-страницы как статической по сравнению с простой загрузкой нестатической с помощью express?
PositiveGuy

14

Я также столкнулся с той же проблемой в express 3.Xи node 0.6.16. Приведенное выше решение не будет работать для последней версии express 3.x. Они удалили app.registerметод и добавили app.engineметод. Если вы попробовали вышеуказанное решение, вы можете получить следующую ошибку.

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)

Чтобы избавиться от сообщения об ошибке. Добавьте следующую строку в вашapp.configure function

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

Примечание: вы должны установить ejsшаблонизатор

npm install -g ejs

Пример:

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

Примечание. Самое простое решение - использовать шаблон ejs в качестве движка представления. Там вы можете написать необработанный HTML в * .ejs файлах просмотра.


3
Вы должны установить ejsглобально?
Дрю Ноакс

он говорит мне, что не может найти файл index.html
MetaGuru

9

структура папок:

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

вывод:

Привет мир


7

Если вам не нужно использовать каталог views , просто переместите html-файлы в публичный каталог ниже.

и затем добавьте эту строку в app.configure вместо '/ views'.

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

5

Чтобы отобразить HTML-страницу в узле, попробуйте следующее:

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

app.engine('html', require('ejs').renderFile);
  • Вам нужно установить ejsмодуль через npm:

       npm install ejs --save

Это решение сработало для меня. Хотя я тоже попробовал статический вариант. Можете ли вы объяснить механизм, стоящий за этим. Спасибо!
19

4

Для моего проекта я создал эту структуру:

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

Этот код служит index.html для /запросов и reset.css для /css/reset.cssзапросов. Достаточно просто, и самое приятное, что он автоматически добавляет заголовки кеша .

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) Лучший способ - установить статическую папку. В вашем главном файле (app.js | server.js | ???):

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

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

Затем вы получили статический файл из «публичной» папки:

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

2)

Вы можете создать свой файловый кеш.
Используйте метод 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"] );                                
};);

неплохо! вот полная демонстрационная версия файла! https://gist.github.com/xgqfrms-GitHub/7697d5975bdffe8d474ac19ef906e906
xgqfrms

3

В Express 4.0.0 единственное, что вам нужно сделать, это закомментировать 2 строки в app.js:

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

А затем поместите ваш статический файл в каталог / public. Пример: /public/index.html


3

Я добавил ниже 2 строки, и это работает для меня

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

это дает мне следующую ошибку «Ошибка: не удается найти модуль 'ejs' в Function.Module._resolveFilename (module.js: 338: 15) в Function.Module._load (module.js: 280: 25) в Module.require ( module.js: 364: 17) по требованию («module.js: 380: 17)»
Lygub Org

@LygubOrg запускается npm install ejs --saveв вашем рабочем каталоге.
A1rPun

1
Нужно ли добавлять зависимость только для обслуживания HTML-файла?
JCarlosR

3

Попробуйте функцию res.sendFile () в экспресс-маршрутах.

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

Читайте здесь: http://codeforgeek.com/2015/01/render-html-file-expressjs/


3

Я не хотел зависеть от ejs для простой доставки HTML-файла, поэтому я просто написал крошечный рендер:

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

Я пытался настроить угловое приложение с экспресс-API RESTful и несколько раз попадал на эту страницу, хотя это было бесполезно. Вот что я нашел, что сработало:

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

Тогда в обратном вызове для ваших маршрутов API выглядят так: res.jsonp(users);

Ваш клиентский фреймворк может обрабатывать маршрутизацию. Экспресс для обслуживания API.

Мой домашний маршрут выглядит так:

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

Вот полная демонстрационная версия файла экспресс-сервера!

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

надеюсь, это поможет вам!

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

Добавьте следующие строки в ваш код

  1. Замените "jade" на "ejs" и "XYZ" (версия) на "*" в файле package.json

      "dependencies": {
       "ejs": "*"
      }
  2. Затем в вашем файле app.js добавьте следующий код:

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

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

  3. И Помните: Сохраняйте все .HTML-файлы в папке просмотра

Ура :)


1

Для простого HTML вам не требуется пакет npm или промежуточное ПО

просто используйте это:

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

1

Очень печально, что около 2020 года экспресс еще не добавил способ рендеринга HTML-страницы без использования sendFileметода responseобъекта. Использование sendFileне является проблемой, но передача аргумента в форме path.join(__dirname, 'relative/path/to/file')не кажется правильным. Почему пользователь должен присоединиться __dirnameк пути к файлу? Это должно быть сделано по умолчанию. Почему корень сервера не может быть удален из каталога проекта? Кроме того, установка шаблонной зависимости просто для рендеринга статического HTML-файла снова не является правильной. Я не знаю правильный способ решения этой проблемы, но если бы мне пришлось обслуживать статический HTML, я бы сделал что-то вроде:

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

В приведенном выше примере предполагается, что структура проекта имеет viewsкаталог и статические файлы HTML находятся внутри него. Например, скажем, в viewsкаталоге есть два HTML-файла с именами, index.htmlи about.html, чтобы получить к ним доступ, мы можем посетить: localhost:8153/index.htmlили просто localhost:8153/загрузить index.htmlстраницу и localhost:8153/about.htmlзагрузить about.html. Мы можем использовать аналогичный подход, чтобы обслуживать реактивное / угловое приложение, сохраняя артефакты в viewsкаталоге или просто используя dist/<project-name>каталог по умолчанию и настраивая его на сервере js следующим образом:

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

0

Я хотел, чтобы запросы к "/" обрабатывались по маршруту Express, где ранее они обрабатывались промежуточным ПО статики. Это позволило бы мне отображать обычную версию index.html или версию, которая загружала объединенные + минимизированные JS и CSS, в зависимости от настроек приложения. Вдохновленный ответом Эндрю Гомера , я решил перетащить мои HTML-файлы - без изменений - в папку представлений, настроить Express так

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

И создал обработчик маршрута так

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

Это сработало довольно хорошо.


0

В 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

Если вы пытаетесь обработать HTML-файл, в котором УЖЕ есть все его содержимое, то его не нужно «отображать», его просто нужно «обслуживать». Рендеринг - это когда сервер обновляет или внедряет контент до того, как страница отправляется в браузер, и требует дополнительных зависимостей, таких как ejs, как показывают другие ответы.

Если вы просто хотите направить браузер в файл на основе их запроса, вы должны использовать res.sendFile () следующим образом:

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

Таким образом, вам не нужны дополнительные зависимости, кроме экспресс. Если вы просто хотите, чтобы сервер отправлял уже созданные html-файлы, приведенный выше способ является очень простым.


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

Поместите ваш файл index.html в общую папку

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

Теперь запустите следующий код в вашем терминале

узел index.js


0

Экспресс 4.х

Отправить .html файлы, без шаблонизатора ...

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

Я обычно использую это

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

Просто будьте осторожны, потому что это будет делиться чем угодно в каталоге / web.

Я надеюсь, что это помогает


-2

если вы используете Express Framework для node.js

установить npm ejs

затем добавьте файл конфигурации

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)

;

рендеринг страницы из модуля export.js имеет html-файл в директории views с расширением имени файла ejs как form.html.ejs

затем создайте form.js

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


Что это за беспорядок?
Вигнеш Раут
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.