AngularJS html5Mode使用Grunt connect。grunt 0.4.5

20

我最近切换到 grunt 0.4.5,并且它改变了 connect 的工作方式。

我之前使用了 connect-modrewrite,效果还不错(对于 /:parameter 生成的 URL 有些问题)。

这是旧版本,在使用 grunt 0.4.1 和 generator-angular 0.8.0 中正常工作的代码,其中中间件部分由我修改以使用 html5mode。

connect: {
    options: {
        port: 9000,
        hostname: '*IP HERE*',
        livereload: 35729,
        middleware: function (connect, options) {
            var optBase = (typeof options.base === 'string') ? [options.base] : options.base;
            return [require('connect-modrewrite')(['!(\\..+)$ / [L]'])].concat(
                optBase.map(function(path){ return connect.static(path); })
            );
        }
    },
    livereload: {
        options: {
            open: true,
            base: [
                '.tmp',
                '<%= yeoman.app %>'
            ]
        }
    },

这是来自generator-angular 0.9.0-1的新版本。
connect: {
    options: {
        port: 9000,
        hostname: '*IP HERE*',
        livereload: 35729
    },
    livereload: {
        options: {
            open: true,
            middleware: function (connect) {
                return [
                    connect.static('.tmp'),
                    connect().use(
                        '/bower_components',
                        connect.static('./bower_components')
                    ),
                    connect.static(appConfig.app)
                ];
            }
        }
    },

如何将此更改为使用mod-rewrite或任何其他方法来实现html5mode?
我尝试使用这里提供的方法:https://gist.github.com/nnarhinen/7719157 我将其组合起来创建了以下内容:
middleware: function (connect) {
    return [
        connect.static(modRewrite(['^[^\\.]*$ /index.html [L]'])),
        connect.static('.tmp'),
        connect().use(
            '/bower_components',
            connect.static('./bower_components')
        ),
        connect.static(appConfig.app)
    ];
}

这让我能够查看正常视图,但是modRewrite部分似乎没有按照需要的方式来通过URL获取其他视图。

奇怪,我目前正在使用grunt 0.4.5,中间件运行良好。我尝试了许多不同的实现方式,这是唯一一个可以与“base”选项一起使用的。 - Evan Plaice
4个回答

65
如果其他人遇到同样的问题,这里有一个解决方法:(唯一添加的一行是modRewrite行)
livereload: {
    options: {
        open: true,
        middleware: function (connect) {
            return [
                modRewrite(['^[^\\.]*$ /index.html [L]']),
                connect.static('.tmp'),
                connect().use(
                    '/bower_components',
                    connect.static('./bower_components')
                ),
                connect.static(appConfig.app)
            ];
        }
    }
},

请确保在您的Grunt文件顶部声明以下内容:
var modRewrite = require('connect-modrewrite');

7
请确保安装了connect-modrewrite模块 npm install connect-modrewrite --save-dev - jubalm
1
谢谢!有很多文章解释旧版本的内容。我已经尝试了五种不同的方法都没有成功。我尝试了这个解决方案,它完美地工作了。 - leticia
@Kryx,关于支持另一种进制的问题怎么样? - Evan Plaice
@EvanPlaice 我完全不知道它与此如何交互。 - Mark Lenser
2
我按照这种方法操作,但在/:params方面仍然存在问题。加载main.css的URL前缀是当前URL而不是基本路径。就像http://localhost:9000/mypage/styles/main.css(加载404失败)而不是http://localhost:9000/styles/main.css。 - mnm
嘿,谢谢,对我的情况完美地起作用了。另一个问题,@Kryx,如果我想在生产服务器上实现相同的行为,您知道Nginx的相应配置吗? - ikenator

7

考虑到其他答案都相当冗长,并且不保留默认的grunt-contrib-connect中间件,我想出了一种解决方案,它使用了专用中间件-connect-history-api-fallback

npm install connect-history-api-fallback --save-dev

var history = require('connect-history-api-fallback')
//...
connect: {
    options: {
        middleware: function(connect, options, middleware) {
            middleware.unshift(history())
            return middleware
        },
        //...
    },
    //...
}

3

虽然上面的答案是正确的。我添加了我使用的配置,它在CentOs上完美运行。

以下1至3步是为了使Angularjs清理URL在您的本地机器上使用$ grunt serve正常工作

但是,如果您想让它们在服务器上良好运行,特别是nginx,您还需要更新nginx配置。(第4步)

  1. $ npm install connect-modrewrite --save

  2. Edit your gruntfile.js. Add at the top of the file

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

接着在你的 middleware 中:

middleware: function (connect) {
    return [
        modRewrite(['^[^\\.]*$ /index.html [L]']),
        connect.static('.tmp'),
        connect().use('/bower_components',
        connect.static('./bower_components')),
        connect.static(config.app)
    ];
}

例如。
// Generated on 2015-11-09 using generator-angular 0.14.0
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'
var modRewrite = require('connect-modrewrite');

module.exports = function (grunt) {

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

3.然后进入Livereload中间件,添加modRewrite

livereload: {
    options: {
        middleware: function (connect) {
            return [
                modRewrite([
                  '^[^\\.]*$ /index.html [L]'
                ]),
                connect.static('.tmp'),
                connect().use('/bower_components', connect.static('./bower_components')),
                connect.static(config.app)
            ];
        }
    }
},

4.编辑NGINX配置文件:

server {
    server_name yoursite.com;
    root /usr/share/html;
    index index.html;

    location / {
    try_files $uri $uri/ /index.html;
    }
}

希望能帮到您 :)

1
这是我的解决方案,适用于generator-angular设置,但可以在任何地方使用。它允许重写语法(有趣的部分是示例livereload配置)。
connect: {
  options: {
    port: 9000,
    // Change this to '0.0.0.0' to access the server from outside.
    hostname: 'localhost',
    livereload: 35729,
    // Modrewrite rule, connect.static(path) for each path in target's base
    middleware: function (connect, options) {
      var optBase = (typeof options.base === 'string') ? [options.base] : options.base,
          middleware = [require('connect-modrewrite')(['!(\\..+)$ / [L]'])]
            .concat(optBase.map(function (path) { 
              if (path.indexOf('rewrite|') === -1) {
                return connect.static(path);
              } else {
                path = path.replace(/\\/g, '/').split('|');
                return  connect().use(path[1], connect.static(path[2]))
              }
            }));

      return middleware;
    }
  },
  livereload: {
    options: {
      open: true,
      base: [
        '.tmp',
        'rewrite|/bower_components|./bower_components',
        'rewrite|/app/styles|./app/styles', // for sourcemaps
        '<%= yeoman.app %>'
      ]
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接