Using grunt server, how can I redirect all requests to root url?

偶尔善良 提交于 2019-11-28 15:53:20
Zuriel

First, using your command line, navigate to your directory with your gruntfile.

Type this in the CLI:

npm install --save-dev connect-modrewrite

At the top of your grunt file put this:

var modRewrite = require('connect-modrewrite');

Now the next part, you only want to add modRewrite into your connect:

modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png$ /index.html [L]']),

Here is a example of what my "connect" looks like inside my Gruntfile.js. You don't need to worry about my lrSnippet and my ssIncludes. The main thing you need is to just get the modRewrite in.

        connect: {
        options: {
            port: 9000,
            // Change this to '0.0.0.0' to access the server from outside.
            hostname: '0.0.0.0',
        },
        livereload: {
            options: {
                middleware: function (connect) {
                return [
                        modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png$ /index.html [L]']),
                        lrSnippet,
                        ssInclude(yeomanConfig.app),
                        mountFolder(connect, '.tmp'),
                        mountFolder(connect, yeomanConfig.app)
                        ];
                }
            }
        },
        test: {
            options: {
                middleware: function (connect) {
                    return [
                    mountFolder(connect, '.tmp'),
                    mountFolder(connect, 'test')
                    ];
                }
            }
        },
        dist: {
            options: {
                middleware: function (connect) {
                    return [
                    mountFolder(connect, yeomanConfig.dist)
                    ];
                }
            }
        }
    },

FYI Yeoman/Grunt recently changed the default template for new Gruntfiles.

Copying the default middlewares logic worked for me:

middleware: function (connect, options) {
  var middlewares = [];
  var directory = options.directory || options.base[options.base.length - 1];

  // enable Angular's HTML5 mode
  middlewares.push(modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png$ /index.html [L]']));

  if (!Array.isArray(options.base)) {
    options.base = [options.base];
  }
  options.base.forEach(function(base) {
    // Serve static files.
    middlewares.push(connect.static(base));
  });

  // Make directory browse-able.
  middlewares.push(connect.directory(directory));

  return middlewares;
}

UPDATE: As of grunt-contrib-connect 0.9.0, injecting middlewares into the connect server is much easier:

module.exports = function (grunt) {
  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);
  grunt.initConfig({
    // The actual grunt server settings
    connect: {
      livereload: {
        options: {
         /* Support `$locationProvider.html5Mode(true);`
          * Requires grunt 0.9.0 or higher
          * Otherwise you will see this error:
          *   Running "connect:livereload" (connect) task
          *   Warning: Cannot call method 'push' of undefined Use --force to continue.
          */
          middleware: function(connect, options, middlewares) {
            var modRewrite = require('connect-modrewrite');

            // enable Angular's HTML5 mode
            middlewares.unshift(modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png$ /index.html [L]']));

            return middlewares;
          }
        }
      }
    }
  });
}

There is a pull request I sent for this problem: https://github.com/yeoman/generator-angular/pull/132, but you need to apply it manually.

To deeply simplify @Zuriel's answer, here's what I found to work on my behalf.

  • Install connect-modrewrite: npm install connect-modrewrite --save
  • Include it in your grunt file: var rewrite = require( "connect-modrewrite" );
  • Modify your connect options to use the rewrite:

    connect: {  
        options: {  
            middleware: function ( connect, options, middlewares ) {
                var rules = [
                    "!\\.html|\\.js|\\.css|\\.svg|\\.jp(e?)g|\\.png|\\.gif$ /index.html"
                ];
                middlewares.unshift( rewrite( rules ) );
                return middlewares;
            }
        },
        server: {
            options: {
                port: 9000,
                base: "path/to/base"
            }
        }
    }  
    

Simplified this as much as possible. Because you have access to the middlewares provided by connect, it's easy to set the rewrite to the first priority response. I know it's been a while since the question has been asked, but this is one of the top results of google searching regarding the problem.

Idea came from source code: https://github.com/gruntjs/grunt-contrib-connect/blob/master/Gruntfile.js#L126-L139
Rules string from: http://danburzo.ro/grunt/chapters/server/

I tried all of these, but had no luck. I am writing an angular2 app, and the solution came from grunt-connect pushstate. All I did was:

npm install grunt-connect-pushstate --save

and in the grunt file:

var pushState = require('grunt-connect-pushstate/lib/utils').pushState;
middleware: function (connect, options) {
  return [
    // Rewrite requests to root so they may be handled by router 
    pushState(),

    // Serve static files 
    connect.static(options.base)
  ];
}

and it all worked like magic.

https://www.npmjs.com/package/grunt-connect-pushstate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!