Search code examples
node.jsgulpgulp-connect

Gulp connect, serving some assets from a directory different from 'root'


I wonder if it is possible with gulp-connect to serve some files from a different directory. Something like:

http://localhost:8080/index.html => root: '/root/app'

but

http://localhost:8008/js/main.js => from '/root/js/' not from 'root/app/js' 
http://localhost:8008/css/main.css => from '/root/css/' not from 'root/app/css/' 

Solution

  • You can pass a middleware function to gulp-connect that allows you to modify the request object and therefore rewrite request URLs:

    gulp.task('serve', function() {
      connect.server({
        root: 'root',
        middleware: function() {
          return [ function(req, res, next) {
            if (!/^\/(js|css)\/.*/.test(req.url)) {
              req.url = '/app' + req.url;
            }
            next();
          }];
        }
      });
    });
    

    In the above any path that starts with /js/ or /css/ will be passed through unchanged. Since our base folder is root that means a path like /js/main.js will resolve to root/js/main.js.

    All other paths will be prepended with /app, meaning a path like /index.html will transparently resolve to root/app/index.html.

    Instead of using custom logic as I did above, you can also use something like http-rewrite-middleware, which allows you to specify nginx-inspired rewrite expressions:

    var rewrite = require('http-rewrite-middleware');
    
    gulp.task('serve', function() {
      connect.server({
        root: 'root',
        middleware: function() {
          return [ rewrite.getMiddleware([
            { from: '^/js/(.*)$', to: '/js/$1' },
            { from: '^/css/(.*)$', to: '/css/$1' },
            { from: '^(.*)$', to: '/app/$1' }
          ])];
        }
      });
    });