我正在构建我的第一个Angular.js应用程序,并且我正在使用Yeoman。
Yeoman使用Grunt允许您使用命令' grunt server'来运行node.js连接服务器。
我在html5模式下运行我的角度应用程序。根据angular docs,这需要修改服务器以将所有请求重定向到应用程序的根目录(index.html),因为角度应用程序是单页面ajax应用程序。
"使用[html5]模式需要在服务器端重写URL,基本上你必须重写所有链接到应用程序的入口点(例如index.html)"
我试图解决的问题详见this问题。
如何修改我的grunt服务器以将所有页面请求重定向到index.html页面?
答案 0 :(得分:52)
首先,使用命令行,使用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)
];
}
}
}
},
答案 1 :(得分:24)
FYI Yeoman / Grunt最近更改了新Gruntfiles的默认模板。
Copying the default middlewares logic为我工作:
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;
}
}
}
}
});
}
答案 2 :(得分:7)
我发送了一个针对此问题的拉取请求:https://github.com/yeoman/generator-angular/pull/132,但您需要手动应用它。
答案 3 :(得分:5)
为了深入简化@ Zuriel的回答,这是我发现代表我工作的内容。
npm install connect-modrewrite --save
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搜索问题的最佳结果之一。
创意来自源代码:https://github.com/gruntjs/grunt-contrib-connect/blob/master/Gruntfile.js#L126-L139
规则字符串来自:http://danburzo.ro/grunt/chapters/server/
答案 4 :(得分:0)
我尝试了所有这些,但没有运气。我正在写一个angular2应用程序,解决方案来自grunt-connect pushstate。 我所做的只是:
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)
];
}
这一切都像魔术一样。