Reputation: 175
This has been asked before and I have tried a variety of suggested pathing approaches, but I have yet to figure out how to do it for my case.
I am aware of using ...
1) app.use(express.static(path.join(process.env.PWD, 'public')));
2) app.use(express.static('./public')));
3) app.use(express.static(path.join(__dirname, 'public')));
Locally, options 1 and 2 work but when deployed to Heroku do not work. Options 3 does not work locally.
I think I have figured out why it's not working, which is that the app.use configuration is not used within the js file that starts the server (e.g. server.js). The app.use configuration is located in another file(called express.js) that's in another directory.
This is my setup
asmtax
--app
--controllers
--models
--routes
--views
--config
--express.js
--public
--css
--js
--images
--server.js
Here is my express.js file
process.env.PWD = process.cwd();
var config = require('./config');
var express = require('express');
var morgan = require('morgan');
var compress = require('compression');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var session = require('express-session');
var flash = require('connect-flash');
var passport = require('passport');
var path = require('path');
module.exports = function() {
//initialize express app
var app = express();
if(process.env.NODE_ENV === 'development') {
app.use(morgan('dev'));
} else if(process.env.NODE_ENV === 'production') {
app.use(compress());
}
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
app.use(methodOverride());
app.use(session({
saveUninitialized: true,
resave: true,
secret: config.sessionSecret
}));
app.set('views', './app/views');
app.set('view engine', 'ejs');
require('../app/routes/index.server.routes.js')(app);
require('../app/routes/about.server.routes.js')(app);
app.use(express.static(path.join(process.env.PWD, 'public')));
return app;
};
This is my server.js file
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
var port = process.env.PORT || 3000;
var express = require('./config/express');
var app = express();
app.listen(port, function () {
console.log('listening on port ' + port);
console.log(require('fs').existsSync(__dirname + '/public'));
});
module.exports = app;
Any suggestions on how to get this to work?
Upvotes: 4
Views: 4448
Reputation: 658
I'm not sure that it matters, but the answer from @sheldonk has a / buried in his usage of path.join still. I went with something slightly different that works well, but it was built on top of his answer, so I gave his answer a plus 1 for the inspiration.
app.use(express.static(path.join(__dirname, '..', 'public')));
path.join supports N arguments and combines them all together appropriately.
Upvotes: 2
Reputation: 1580
For me, __dirname does work. My JS-containing folder happened to be capitalized in my layout file, but wasn't in the folder structure.
So, like /public/Bootstrap/js was causing probs. Renamed it to /public/bootstrap/js, and that works just fine, even with __dirname.
Upvotes: 0
Reputation: 2694
Try
app.use(express.static(path.join(__dirname, '../public')));
__dirname refers to the directory of the file. Since 'express.js' is in the config directory. You need to go up one level to access public.
Upvotes: 2