web-dev-qa-db-fra.com

En utilisant le serveur grunt, comment puis-je rediriger toutes les demandes vers l'URL racine?

Je crée ma première application Angular.js et j'utilise Yeoman .

Yeoman utilise Grunt pour vous permettre d'exécuter un serveur de connexion node.js avec la commande 'grunt server'.

J'exécute mon angular en mode html5. Selon les documents angular, cela nécessite une modification du serveur pour rediriger toutes les demandes vers la racine de l'application (index.html), car les applications angular sont des applications ajax à page unique).

"L'utilisation du mode [html5] nécessite une réécriture d'URL côté serveur, fondamentalement vous devez réécrire tous vos liens vers le point d'entrée de votre application (par exemple index.html)"

Le problème que j'essaie de résoudre est détaillé dans this question.

Comment puis-je modifier mon serveur grunt pour rediriger toutes les demandes de page vers la page index.html?

46
Charlie Martin

Tout d'abord, en utilisant votre ligne de commande, accédez à votre répertoire avec votre gruntfile.

Tapez ceci dans la CLI:

npm install --save-dev connect-modrewrite

En haut de votre fichier grunt, mettez ceci:

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

Maintenant, la partie suivante, vous voulez seulement ajouter modRewrite dans votre connexion:

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

Voici un exemple de ce à quoi ressemble ma "connexion" dans mon Gruntfile.js. Vous n'avez pas à vous soucier de mon lrSnippet et de mon ssIncludes. La principale chose dont vous avez besoin est d'obtenir simplement le modRewrite.

        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)
                    ];
                }
            }
        }
    },
52
Zuriel

FYI Yeoman/Grunt a récemment changé le modèle par défaut pour les nouveaux fichiers Grunt.

Copie de la logique des middlewares par défaut a fonctionné pour moi:

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;
}

MISE À JOUR: À partir de grunt-contrib-connect 0.9.0, l'injection de middlewares dans le serveur de connexion est beaucoup plus facile:

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;
          }
        }
      }
    }
  });
}
24
Steve Jansen

Il y a une demande d'extraction que j'ai envoyée pour ce problème: https://github.com/yeoman/generator-angular/pull/132 , mais vous devez l'appliquer manuellement.

7
L42y

Pour simplifier profondément la réponse de @ Zuriel, voici ce que j'ai trouvé pour travailler en mon nom.

  • Installez connect-modrewrite: npm install connect-modrewrite --save
  • Incluez-le dans votre fichier grunt: var rewrite = require( "connect-modrewrite" );
  • Modifiez vos options de connexion pour utiliser la réécriture:

    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"
            }
        }
    }  
    

Simplifié cela autant que possible. Parce que vous avez accès aux middlewares fournis par connect, il est facile de définir la réécriture sur la première réponse prioritaire. Je sais que cela fait un moment que la question n'a pas été posée, mais c'est l'un des meilleurs résultats de la recherche Google concernant le problème.

L'idée est venue du code source: https://github.com/gruntjs/grunt-contrib-connect/blob/master/Gruntfile.js#L126-L139
Chaîne de règles de: http://danburzo.ro/grunt/chapters/server/

5
dmaloney.calu

J'ai essayé tout cela, mais je n'ai pas eu de chance. J'écris une application angular2, et la solution est venue de pushstate de grunt-connect. Je n'ai fait que:

npm install grunt-connect-pushstate --save

et dans le fichier grunt:

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)
  ];
}

et tout cela a fonctionné comme par magie.

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

0
Tomer Almog