Setting up two different static directories in node.js Express framework

Staticnode.jsExpressDuostack

Static Problem Overview


Is it possible? I would like to set up two different directories to serve static files. Let's say /public and /mnt

Static Solutions


Solution 1 - Static

You can also set the path that static files will be served to the web from by specifying an additional (first) parameter to use() like so:

app.use("/public", express.static(__dirname + "/public"));
app.use("/public2", express.static(__dirname + "/public2"));

That way you get two different directories on the web that mirror your local directories, not one url path that fails over between two local directories.

In other words the URL pattern:

http://your.server.com/public/*

Serves files from the local directory public while:

http://your.server.com/public2/*

Serves files from the local directory public2.

BTW this is also useful if you don't want static to serve the files from the root of your server but rather from a more qualified path.

HTH

Solution 2 - Static

You can also "merge" directories into a single visible directory

Directory Structure

  • /static
  • /alternate_static

Code

app.use("/static", express.static(__dirname + "/static"));
app.use("/static", express.static(__dirname + "/alternate_static"));

Both static and alternate_static will be served as if they were in the same directory. Watch out for filename clobbers, though.

Solution 3 - Static

It's not possible by one middleware injection, but you can inject static middleware multiple times:

app.configure('development', function(){
    app.use(express.static(__dirname + '/public1'));
    app.use(express.static(__dirname + '/public2'));
});

Explanation

Look at connect/lib/middleware/static.js#143:

path = normalize(join(root, path));

There is options.root is static root, which you define in express.static or connect.static call, and path is request path.

Look more at connect/lib/middleware/static.js#154:

  fs.stat(path, function(err, stat){
    // ignore ENOENT
    if (err) {
      if (fn) return fn(err);
     return ('ENOENT' == err.code || 'ENAMETOOLONG' == err.code)
       ? next()
       : next(err);

Path checked only once, and if file not found request passed to next middleware.

Update for Connect 2.x

Links to code are inactual for Connect 2.x, but multiple static middleware usage are still posible as before.

Solution 4 - Static

const express = require('express');
const path = require('path');
const pagesPath = path.join(__dirname, '/cheatsheet');
const cssPath = path.join(__dirname, '/stylesheet');
const port = process.env.PORT || 3000;

var app = express();

app.use("/cheatsheet" ,express.static(pagesPath));
app.use("/stylesheet",express.static(cssPath)); 

app.get('/',(request,response)=>{
    response.send('Hello CSS!!!');
  });

app.get('/bad',(request,response)=>{
response.send({error: 'Bad Request'});

});
app.listen(port, ()=> {
console.log(`Server is running on Port ${port}` );
console.log(__dirname);

});

// folder structure
/cheatsheet/index.html
/stylesheet/style.css

Solution 5 - Static

I also faced the same issue but I managed it to resolve it, after a long search for this quest.

Step 1:

Serve the static files in the pathnames of /public and /mnt

app.use('/public', express.static(path.join(__dirname, '<path_to_the_folder_you_want_to_serve_public>')));

app.use('/mnt', express.static(path.join(__dirname, '<path_to_the_folder_you_want_to_serve_mnt>')));

Step 2:

My plan was to deploy two Angular client apps in a single NodeJS server.

So I ran the 'ng build' on both Angular client apps.

I placed one of dist folder in '/public' folder and another dist folder in '/mnt'.

Step 3:

Need to modify the index.html by changing the following things to show the public folder content,

<script src="./public/runtime.js" defer></script>
<script src="./public/polyfills.js" defer></script>
<script src="./public/styles.js" defer></script>
<script src="./public/vendor.js" defer></script>
<script src="./public/main.js" defer></script>

Need to modify the index.html by changing the following things to show the mnt folder content,

<script src="./mnt/runtime.js" defer></script>
<script src="./mnt/polyfills.js" defer></script>
<script src="./mnt/styles.js" defer></script>
<script src="./mnt/vendor.js" defer></script>
<script src="./mnt/main.js" defer></script>

Important Note : Change the .js files path based on the static folder serving path.

Step 4:

In one path, you can serve public and on another you can serve mnt.

app.get('/', function(req, res) => {
  res.sendFile(path.join(__dirname, '../public/dist/index.html'));
})

app.get('/', function(req, res) => {
  res.sendFile(path.join(__dirname, '../mnt/dist/index.html'));
})

Now you are good to go. Run & Test it.

Solution 6 - Static

To use express.static inside custom middleware:

app.use(customMiddleware())

where

const customMiddleware = function() {
    return function(req, res, next) {
        // do some dynamic code
        // or
        return express.static(__dirname + "/public")(req, res, next);
    }
}

Solution 7 - Static

use :dir instead of *

eg

this.app.use('/:microsite', express.static(path.resolve(process.cwd(), 'client/')))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsNiCKYView Question on Stackoverflow
Solution 1 - StaticfacetcounterView Answer on Stackoverflow
Solution 2 - StaticRandolphoView Answer on Stackoverflow
Solution 3 - StaticPhillip KovalevView Answer on Stackoverflow
Solution 4 - StaticAjay RuhelaView Answer on Stackoverflow
Solution 5 - StaticVijayView Answer on Stackoverflow
Solution 6 - StaticAndi WijayaView Answer on Stackoverflow
Solution 7 - StaticNathView Answer on Stackoverflow