shrewdbeans shrewdbeans - 1 month ago 18
Javascript Question

Running Grunt Express Server causes Error: ENOENT: no such file or directory, open 'static/test.json'

I have a current app that I'm updating to use the Express Node.js library. I have updated the Grunt.js tasks to use the grunt-express-server package. Part of my code is trying access the contents of a JSON file (see directory structure below). It runs the server just fine, but when I try to access any static file I get the following error:

Error: ENOENT: no such file or directory, open 'static/test.json'
at Error (native)
at Object.fs.openSync (fs.js:549:18)
at Object.fs.readFileSync (fs.js:397:15)
at /Users/owen/src/projects/node-express-cannot-get/build/index.js:13:32
at Layer.handle [as handle_request] (/Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/layer.js:95:5)
at /Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/index.js:330:12)


I think this may have something to do with my directory structure and where the Express server is being run from. My Grunt tasks copy all my source files from a folder called src (which contains my index.js) to a folder called build and then runs the server from the Gruntfile which is in the root directory. If I
cd
into the build folder and run index.js directly (
node index.js
), the error goes away. However, running it via the Grunt task produces the error.

How can I fix this issue without changing my directory structure? Is there a way to make the Grunt Express Server task change where it's being run from? Or is there another cause to this issue?

Please see my directory sturcture and code samples below:

Directory structure (after Grunt tasks have completed)

/
build/
static/
test.json
index.js
node_modules/
src/
static/
test.json
index.js
Gruntfile.js
package.json


Gruntfile.js

module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
grunt.config.merge({
clean: {
dev: ['build']
},
mkdir: {
build: {
options: {
mode: 0755,
create: ['build']
}
}
},
copy: {
dev: {
files: [{
expand: true,
cwd: 'src',
src: ['index.js', 'static/**/*'],
dest: 'build'
}]
}
},
express: {
dev: {
options: {
'script': 'build/index.js',
'port': 2000
}
}
},
watch: {
index: {
files: ['index.js'],
tasks: ['clean', 'mkdir', 'copy']
}
}
});
grunt.registerTask('default', [
'clean:dev',
'mkdir:build',
'copy:dev',
'express:dev',
'watch:index'
]);
};


src/index.js

var express = require('express');
var path = require('path');
var fs = require('fs');

var app = express();

app.set('port', (process.env.PORT || 2000));

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

app.get('/', function (req, res) {
configurationPath = 'static/test.json';
// I beleive this is where the problem happens...
var configurationJSON = fs.readFileSync([configurationPath].join("")).toString();
console.log('configurationJSON', configurationJSON);
res.send('Hello world');
});

app.listen(app.get('port'), function () {
console.log('It\'s all go on port: ' + app.get('port') );
});

Answer

The call to readFileSync in index.js is failing because it's passed a relative path - 'static/test.json' - and the current directory is not what you think it is.

The current directory is the directory with the package.json in it - not the build directory.

If you use __dirname - as you've done with the static middleware - it should solve your problem:

var configurationPath = path.join(__dirname, 'static/test.json');