Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am building my first Angular.js application and I'm using Yeoman.

Yeoman uses Grunt to allow you to run a node.js connect server with the command 'grunt server'.

I'm running my angular application in html5 mode. According to the angular docs, this requires a modification of the server to redirect all requests to the root of the application (index.html), since angular apps are single page ajax applications.

"Using [html5] mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html)"

The problem that I'm trying to solve is detailed in this question.

How can I modify my grunt server to redirect all page requests to the index.html page?

like image 805
Charlie Martin Avatar asked Jun 13 '13 06:06

Charlie Martin


Video Answer


2 Answers

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)                     ];                 }             }         }     }, 
like image 157
Zuriel Avatar answered Sep 24 '22 06:09

Zuriel


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;           }         }       }     }   }); } 
like image 23
Steve Jansen Avatar answered Sep 26 '22 06:09

Steve Jansen