On my quest to teach myself Node, Express and various other JS frameworks, I recently built an API serving multiple frontends in one big application. It’s presentend in the same way as TodoMVC where there is a dashboard page with links to other pages, each containing the same app implemented using a different technology.
When I first got started with this project my application structure looked something like this:
- app/
- …Node relates files…
- public/
- Angular-app/
- node_modules/
- package.json
- React-app/
- node_modules/
- package.json
- …
- Angular-app/
- node_modules/
- server.js
- package.json
I had my main server.js file at the top level, next to the app directory which contained all of my Node and Express code, and a public directory with all of my frontend implementations. Why the multiple package.json files and node_module directories you ask? Well, all the tutorials that I read about getting a Node + Express server setup stated that you need to specify a static assets directory to serve up CSS, JS, images files and any other static resources. This can be done using:
app.use(express.static('public'));
And I assumed that only one directory can be set to serve static files and that was that. This was a problem for me, since I didn’t want to manually download all the libraries that I needed and put them in my public folder or copy them using some build tool like Grunt.
I thought I outsmarted the system when I used npm to add dependencies inside of my public folder for each of my mini frontend apps. It looked a bit wrong but hey, everything worked.
Until it didn’t.
Eventually I tried deploying this app to Heroku and Heroku decided that what I had done was a no-no. The problem was that npm won’t recursively scan your app for package.json files and install dependencies accordingly. It was time to get rid of my ‘sweep-it-under-the-rug’ solution and do this the right way.
The right way is really simple – so simple that I had to take a long, hard look in the mirror and question the life choices that led me to miss this in the first place (like not reading the Express Docs). Turns out that you can set more than one directory to serve static resources in Express by just calling the static middleware function again:
app.use(express.static('public')); app.use(express.static('node_modules'));
You can even give the directory a fake reference name, to better mask your server structure from hackers:
app.use('/libraries', express.static('node_modules'));
Now any files in the node_modules directory can be referenced from the frontend applications using libraries instead:
<link rel="stylesheet" href="/libraries/bootstrap/dist/css/bootstrap.min.css">
By using multiple directories to serve static resources in Node and Express you get more freedom when structuring your application. You can define your custom code in one place and your dependencies in another, but still make both available to the entire app.
Leave a Reply