46 votes

En utilisant le serveur grunt, comment puis-je rediriger toutes les requêtes vers l'url Root ?

Je suis en train de construire mon premier Angular.js et j'utilise Yeoman .

Yeoman utilise Grunt pour vous permettre de lancer un serveur de connexion node.js avec la commande 'grunt server'.

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

"L'utilisation du mode [html5] nécessite une réécriture d'URL du côté du serveur. En fait, 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'essaye de résoudre est détaillé dans este question.

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

53voto

Zuriel Points 363

Tout d'abord, en utilisant votre ligne de commande, naviguez dans votre répertoire avec votre gruntfile.

Tapez ceci dans le 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 mon "connect" dans mon Gruntfile.js. Vous n'avez pas besoin de vous soucier de mon lrSnippet et de mes ssIncludes. La principale chose dont vous avez besoin est d'intégrer 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)
                    ];
                }
            }
        }
    },

24voto

Steve Jansen Points 1990

Pour votre information, Yeoman/Grunt a récemment modifié le modèle par défaut des nouveaux Gruntfiles.

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

UPDATE : À partir de grunt-contrib-connect 0.9.0, l'injection d'intergiciels dans le serveur connect 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;
          }
        }
      }
    }
  });
}

7voto

L42y Points 460

J'ai envoyé une demande de retrait pour ce problème : https://github.com/yeoman/generator-angular/pull/132 mais vous devez l'appliquer manuellement.

5voto

dmaloney.calu Points 121

Pour simplifier profondément la réponse de @Zuriel, voici ce qui a fonctionné pour moi.

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

Je l'ai simplifié au maximum. Parce que vous avez accès aux intergiciels fournis par connect, il est facile de définir la réécriture comme la réponse prioritaire. Je sais que cela fait un moment que la question a été posée, mais c'est l'un des premiers résultats de la recherche google concernant ce 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/

0voto

Tomer Almog Points 66

J'ai essayé tout ça, mais sans succès. J'écris une application angular2, et la solution est venue de grunt-connect pushstate. Tout ce que j'ai fait c'est :

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 a fonctionné comme par magie.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X