Al usar el servidor grunt, ¿cómo puedo redirigir todas las solicitudes a la url raíz?

Estoy construyendo mi primera aplicación Angular.js y estoy usando Yeoman .

Yeoman usa Grunt para permitirle ejecutar un servidor node.js connect con el comando ‘grunt server’.

Estoy ejecutando mi aplicación angular en modo html5. Según la documentación angular, esto requiere una modificación del servidor para redirigir todas las solicitudes a la raíz de la aplicación (index.html), ya que las aplicaciones angulares son aplicaciones ajax de una sola página.

“El uso del modo [html5] requiere la reescritura de URL en el servidor, básicamente, debe volver a escribir todos sus enlaces al punto de entrada de su aplicación (por ejemplo, index.html)”

El problema que estoy tratando de resolver se detalla en esta pregunta.

¿Cómo puedo modificar mi servidor grunt para redirigir todas las solicitudes de página a la página index.html?

Primero, usando su línea de comando, navegue a su directorio con su archivo de archivos de texto.

Escriba esto en el CLI:

npm install --save-dev connect-modrewrite 

En la parte superior de su archivo gruñido ponga esto:

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

Ahora en la siguiente parte, solo desea agregar modRewrite a su conexión:

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

Aquí hay un ejemplo de cómo se ve mi “conexión” dentro de mi Gruntfile.js. No tienes que preocuparte por mi lrSnippet y mis ssIncludes. Lo principal que necesitas es simplemente ingresar el 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) ]; } } } }, 

FYI Yeoman / Grunt recientemente cambió la plantilla predeterminada para los nuevos archivos de archivos de grano.

Copiar la lógica predeterminada de middlewares funcionó para mí:

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

ACTUALIZACIÓN: a partir de grunt-contrib-connect 0.9.0, inyectar middlewares en el servidor de conexión es mucho más fácil:

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

Hay una solicitud de extracción que envié para este problema: https://github.com/yeoman/generator-angular/pull/132 , pero debe aplicarla manualmente.

Para simplificar profundamente la respuesta de @Zuriel, esto es lo que encontré para trabajar en mi nombre.

  • Instale connect-modrewrite: npm install connect-modrewrite --save
  • Inclúyalo en su archivo grunt: var rewrite = require( "connect-modrewrite" );
  • Modifique sus opciones de conexión para usar la reescritura:

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

Simplificado esto tanto como sea posible. Debido a que tiene acceso a los middlewares proporcionados por la conexión, es fácil configurar la reescritura a la primera respuesta de prioridad. Sé que ha pasado un tiempo desde que se hizo la pregunta, pero este es uno de los mejores resultados de la búsqueda de Google con respecto al problema.

La idea vino del código fuente: https://github.com/gruntjs/grunt-contrib-connect/blob/master/Gruntfile.js#L126-L139
Cadena de reglas desde: http://danburzo.ro/grunt/chapters/server/

Intenté todo esto, pero no tuve suerte. Estoy escribiendo una aplicación angular2, y la solución vino de pushstate grunt-connect. Todo lo que hice fue:

 npm install grunt-connect-pushstate --save 

y en el archivo gruñido:

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

Y todo funcionó como magia.

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