Currently i'm working on a web application with express.js. I want to have a frontend and backend. The frontend should show some contents from a database, in the backend i want to create this contents (similar as a cms).
I started with this folder structure:
app/
├── frontend/
│ ├── public //Javascript, css & images only for frontend
│ ├── views //Frontend jade templates
│ └── client.js
│
├── backend/
│ ├── public //Only backend css & stuff
│ └── views //Backend templates
│ └── core.js
│
└── server.js //Starts the whole application
The server.js
var express = require('express');
var app = express();
var config = require('../app/config.json')[app.get('env')];
var backend = require('./backend/core');
var frontend = require('./frontend/client');
app.use(backend);
app.use(frontend);
app.set('port', config.port || 3000);
var server = app.listen(app.get('port'), function() {
console.log('Server listening on port ' + app.get('port') + ' in ' + app.get('env') + ' mode');
});
the client.js
var express = require('express');
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res) {
res.render('layout', {title: 'Frontpage'});
});
app.get('/about', function(req, res) {
res.render('layout', {title: 'About us'});
});
module.exports = app;
and the core.js
var express = require('express');
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.static(__dirname + '/public'));
app.get('/login', function(req, res) {
res.render('layout', {title: 'Login'});
});
app.get('/login/dashboard', function(req, res) {
res.render('layout', {title: 'Dashboard'});
});
module.exports = app;
express.js loads the right templates but not the right stylesheet. For every route the backend stylesheet is loaded.
localhost:3000/about
should load the stylesheet in
frontend/public/css/
and
localhost:3000/login
should load the css in
backend/public/css/
How can i fix this?
The issue that the backend stylesheet is served by express is a consequence of how express handles requests in conjunction with your application architecture.
A web browser requests a stylesheet /css/site.css express accepts this request and processes all middleware and routers. Since you set up your main app like this
app.use(backend);
app.use(frontend);
The backend app first handles the request. Since you've registered the static middleware in your backend app
app.use(express.static(__dirname + '/public'));
the stylesheet /css/site.css is served from your backend app if this stylesheet exists. This happens for every middleware and route. So any route or asset (css, image) that is requested by a client will be first processed by your backend app. As a consequence routes and assets in the backend app will "hide" routes and assets in your frontend app if they are served via the same route.
A simple solution to your problem would be that you're not serving backend and frontend apps from your main app but to start two express apps in server.js:
var config = require('../app/config.json')[process.env.NODE_ENV];
var backend = require('./backend/core');
backend.set('port', config.backend.port || 3000);
var backendServer = backend.listen(backend.get('port'), function() {
console.log('Backend server listening on port ' + backend.get('port') + ' in ' + backend.get('env') + ' mode');
});
var frontend = require('./frontend/client');
frontend.set('port', config.frontend.port || 3001);
var frontendServer = frontend.listen(frontend.get('port'), function() {
console.log('Frontend server listening on port ' + frontend.get('port') + ' in ' + frontend.get('env') + ' mode');
});