web-dev-qa-db-ja.com

gruntサーバーを使用して、すべてのリクエストをルートURLにリダイレクトするにはどうすればよいですか?

私は最初の Angular.js アプリケーションを構築しており、 Yeoman を使用しています。

YeomanはGruntを使用して、コマンド「grunt server」でnode.js接続サーバーを実行できるようにします。

angular html5モードでアプリケーションを実行しています。angularのドキュメントによると、これはすべてのリクエストをangularアプリは単一ページのajaxアプリケーションであるため、アプリケーション(index.html)。

「[html5]モードを使用するには、サーバー側でURLを書き換える必要があります。基本的に、アプリケーションのエントリポイントへのすべてのリンクを書き換える必要があります(index.htmlなど)。」

私が解決しようとしている問題は this の質問で詳しく説明されています。

すべてのページリクエストをindex.htmlページにリダイレクトするためにgruntサーバーを変更するにはどうすればよいですか?

46
Charlie Martin

まず、コマンドラインを使用して、gruntfileを使用してディレクトリに移動します。

CLIでこれを入力します。

npm install --save-dev connect-modrewrite

Gruntファイルの先頭にこれを置きます:

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

次のパートでは、接続に modRewrite のみを追加します。

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

Gruntfile.js内の「接続」の例を次に示します。私のlrSnippetとssIncludesについて心配する必要はありません。必要な主なことは、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は最近、新しいGruntfileのデフォルトテンプレートを変更しました。

デフォルトのミドルウェアロジックのコピー 私のために働いた:

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:grunt-contrib-connect 0.9.0の時点では、接続サーバーへのミドルウェアの注入ははるかに簡単です。

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

この問題のために送信したプルリクエストがあります: https://github.com/yeoman/generator-angular/pull/132 ですが、手動で適用する必要があります。

7
L42y

@Zurielの答えを非常に単純化するために、私に代わって仕事をすることがわかった。

  • Connect-modrewriteをインストールします:_npm install connect-modrewrite --save_
  • Gruntファイルにそれを含めます:var rewrite = require( "connect-modrewrite" );
  • リライトを使用するように接続オプションを変更します。

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

これを可能な限り簡素化しました。 connectによって提供されるミドルウェアにアクセスできるため、最初の優先度の応答に書き換えを設定するのは簡単です。質問がされてからしばらく経ちましたが、これは問題に関するGoogle検索の上位の結果の1つです。

アイデアはソースコードから来ました: https://github.com/gruntjs/grunt-contrib-connect/blob/master/Gruntfile.js#L126-L139
ルール文字列: http://danburzo.ro/grunt/chapters/server/

5
dmaloney.calu

これらすべてを試しましたが、運がありませんでした。 Angular2アプリを書いていますが、その解決策は単発接続のプッシュ状態から来ました。私がしたことは:

npm install grunt-connect-pushstate --save

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

そしてそれはすべて魔法のように働きました。

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

0
Tomer Almog