FirstOfMany FirstOfMany - 4 months ago 124
Javascript Question

Error: ENOENT: no such file or directory with Angular2 and Express.js

I am making minor modifications to this sample Angular2 app on GitHub so that it uses Express.js instead of KOA. But at the moment, the following error is printed in the

nodemon
console when I try to load the app in FireFox:

Error: ENOENT: no such file or directory


The Angular2 app starts to load when an http request for
localhost : 8080
triggers the
*
router handler, which returns
index.html
, which then triggers callbacks for a series of nested dependencies, one of which throws the error and halts the application loading mid-way through.

What specific changes need to be made to the code in the GitHub sample in order to resolve the
Error: ENOENT: no such file or directory
?



Background and Code:

Here is the new replacement for
router.js
which uses Express.js instead of KOA:

'use strict';
let uuid = require('node-uuid');
var path = require('path');
let jwt = require('jsonwebtoken');
let config = require('./config');

// expose the routes to our app with module.exports
module.exports = function(app) {

//all other methods omitted here for brevity

app.get('*', function(req, res) {
console.log('inside * route!');
if(req.url === '/'){
res.sendFile(path.resolve('dist/client/index.html')); // load the single view file (angular will handle the front-end)
} else {
res.sendFile(path.resolve('./dist/client' + req.url));
}
});
};


The
nodemon
console output for the request to
localhost : 8080
that triggers the above Express.js
app.get('*'...)
method repeatedly leading up to the error is:

App listening on port 8080
inside * route!
GET / 304 54.261 ms - -
inside * route!
inside * route!
inside * route!
GET /boot.css 304 4.637 ms - -
GET /boot.js 304 4.447 ms - -
GET /vendor.js 304 3.742 ms - -
inside * route!
GET /vendor.js.map 200 3.180 ms - 3115631
inside * route!
GET /boot.js.map 200 2.366 ms - 61810
inside * route!
GET /bootstrap.css.map 404 2.515 ms - 169
Error: ENOENT: no such file or directory, stat '/home/user/nodejs_apps/angular2_oauth_seed_app/dist/client/bootstrap.css.map'
at Error (native)


And the new
server/index.js
which specifies Express.js is:

// set up ======================================================================
var express = require('express');
var app = express(); // create our app w/ express
var port = process.env.PORT || 8080; // set the port
var morgan = require('morgan'); // log requests to the console (express4)
var bodyParser = require('body-parser'); // pull information from HTML POST (express4)
var methodOverride = require('method-override'); // simulate DELETE and PUT (express4)

app.use('/static', express.static(__dirname + '/dist/client'));
app.use(morgan('dev')); // log every request to the console
app.use(bodyParser.urlencoded({'extended':'true'})); // parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
app.use(methodOverride());
app.use('/scripts', express.static(__dirname + '/node_modules/'));

// load the routes
require('./router')(app);

// listen (start app with node server.js) ======================================
app.listen(port);
console.log("App listening on port " + port);


Everything else in the GitHub sample app remains the same as what you see on GitHub with the exception of
package.json
, which merely contains dependencies to support the alterations in
router.js
and
index.js
as shown above.

Answer

bootstrap.css.map indicates that your browser is trying to load a source map (which is a debugging tool) for the Bootstrap CSS.

This will only happen if you have your browser's developer tools open, so not strictly a problem (unless you want to actually debug Bootstrap's CSS). Besides that, it's always possible to other URL's to be requested and yield the same error.

A solution would be to add an explicit error handler to sendFile, and assume that when an error happens, it's because the file doesn't exist (so it should yield a 404 response):

res.sendFile(path.resolve('./dist/client' + req.url), (err) => {
  if (err) return res.sendStatus(404);
});