-2

I have a mean-stack application. By going to https://localhost:3000/#/home, it reads views/index.ejs. Here is the setting in app.js:

var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.all('/*', function(req, res, next) {
    res.sendFile('index.ejs', { root: __dirname });
});

Actually, I don't use the feature of ejs in index.ejs. So now I want to use just a index.html rather than index.ejs.

I put the content of index.ejs in public/htmls/index.html and views/index.html. And here is the current setting in app.js:

var app = express();
// app.set('views', path.join(__dirname, 'views'));
// app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.all('/*', function(req, res, next) {
    res.sendFile('index.html', { root: __dirname });
    // res.sendFile('index.html'); // does not work either
});

However, running https://localhost:3000/#/home returns

Error: No default engine was specified and no extension was provided.

Does anyone know how to fix it?

Edit 1: by following the answer of user818510, I tried res.sendFile('index.html', { root: path.join(__dirname, 'views') }); in app.js, it still can NOT find index.html.

Whereas, in routes/index.js, the following can find index.html, but it gives a warning express deprecated res.sendfile: Use res.sendFile instead routes/index.js:460:9.

var express = require('express');
var router = express.Router();
var path = require('path');
... ...
router.get('*', function(req, res) {
    res.sendfile('./views/index.html'); // works, but a deprecation warning
    // res.sendFile('index.html', { root: path.join(__dirname, 'views') }); does not work
});

It is really confusing...

SoftTimur
  • 5,630
  • 38
  • 140
  • 292

3 Answers3

2

If it's a single page mean application, then you only need to start express with static and put index.html in static/ dir :

Project layout

static/
  index.html
server.js

server.js

'use strict';

var express = require('express');

var app = express();
app.use(express.static('public'));

var server = app.listen(8888, function () {
  console.log("Server started. Listening on port %s", server.address().port);
});

Now you can call http://localhost:8888/#home

Stephane Janicaud
  • 3,531
  • 1
  • 12
  • 18
  • 1
    It's only an example... Any url can be called. Using `#` or not is up to you, With angularjs it's called html5mode https://scotch.io/tutorials/pretty-urls-in-angularjs-removing-the-hashtag – Stephane Janicaud May 21 '17 at 07:06
0

It looks like a problem with the path. Your index.html is located at public/htmls/index.html and views/index.html. Your root option in res.sendFile should be __dirname+/public/htmls/ or __dirname+/views

In your code, you are using the path:

res.sendFile('index.html', { root: __dirname });

Your app.js would be in the project root where you have public directory alongside at the same level. Based on your rootoption in res.sendFile, you would have to place index.html at the same level as your app.js.

You should change the root path in res.sendFile. Use:

res.sendFile('index.html', { root: path.join(__dirname, 'public', 'htmls') });

OR

res.sendFile('index.html', { root: path.join(__dirname, 'views') });

The above root is based on the path that you've mentioned in your question.

Here's the link to the docs: http://expressjs.com/en/api.html#res.sendFile

Your no default engine error is probably because you have commented the line where you set the view engine to ejs but still have existing ejs views. Uncommenting that line with the root path change should solve your issue.

user818510
  • 3,414
  • 26
  • 17
  • @SoftTimur Does it work when you remove the `root` option in `res.sendFile` and specify the absolute path for `index.html`? – user818510 May 22 '17 at 09:41
  • Both `res.sendFile('./views/index.html')` and `res.sendfile('./views/index.html')` return a `404` error. – SoftTimur May 22 '17 at 14:01
  • @SoftTimur I meant using the full absolute path. Something like `/home/test/yourapp/views/index.html`. To check this, you'll also need to remove the root option. – user818510 May 22 '17 at 15:55
-2

Do not serve static content from an application server.

Use a web server for that, and in production, a content delivery network like Akamai.

A content delivery network will charge you per bandwidth (e.g: 10 cents per Terabyte). Serving the equivalent of 10 cents in Akamai can cost you thousands of dollars using cloud instances.

In addition to that, your servers will have unnecessary load.

If you absolutely have to serve static content from your application servers, then put a reverse proxy cache like nginx, varnish or squid in front of your server. But that will still be very cost inefficient. This is documented in the express website.

This is common practice in every Internet company.

arboreal84
  • 2,086
  • 18
  • 21