使用Yeoman初始化的项目会默认使用Grunt作为构建工具,Grunt配置了connect任务,可以直接使用命令“grunt serve”在本机启动一个用于预览的Web服务器,默认监听了9000端口,另外,启动的预览服务器还会额外监听35729端口用来即时检测项目的文件是否被更改,一旦在任意编辑器修改了项目所属的文件时,服务器就会即时通过35729端口通知浏览器自动刷新打开的页面,此功能极大的提升了前端的开发效率,如果配置了多台显示器在写代码时更是得心应手。
在开发单个项目时,Yeoman的grunt serve命令没有任何问题,但是如果有两个或更多项目需要并行开发,则会遇到端口冲突的错误,虽然可以在Gruntfile.js文件里面的修改端口配置解决此问题,但项目多了就不知道哪些端口是可用的了,对于钟爱自动化的我简直是件不能忍受的事情,下面给出我的解决方法,分别是自动分配端口和手动配置端口两种方案的详细步骤:
自动分配端口
使用编辑器打开项目根目录的Gruntfile.js;
注册一个自定义的Grunt Task,Task名称随便定义,这里我用“setServerPort”做为示范,Task配置的代码片段如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28// 自定义一个 Grunt Task,用来自动给预览服务器和即时刷新服务分配随即端口;
grunt.registerTask('setServerPort', function() {
var freeport = require('freeport');
var times = 0;
var async = this.async();
function done() {
if (times === 2) {
async();
}
}
// 获取一个空闲端口
// 并设置为预览服务器的端口;
freeport(function(err, port) {
grunt.config.set('connect.options.port', port);
times += 1;
done();
});
// 获取一个空闲端口
// 并设置为即时刷新服务的端口;
freeport(function(err, port) {
grunt.config.set('connect.options.livereload', port);
times += 1;
done();
});
});将上面注册的Task:“setServerPort”注入Task “server”内:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21var desc = 'start the server and preview your app, --allow-remote for remote access';
grunt.registerTask('serve', desc, function (target) {
if (grunt.option('allow-remote')) {
grunt.config.set('connect.options.hostname', '0.0.0.0');
}
if (target === 'dist') {
return grunt.task.run(['build', 'connect:dist:keepalive']);
}
grunt.task.run([
'setServerPort', // <= 将注册的自定义Task "setServerPort" 注入在此处。
'clean:server',
'wiredep',
'concurrent:server',
'autoprefixer',
'connect:livereload',
'watch'
]);
});修改 Task “watch” 内所有属性名为livereload的options的值如下:
1
2
3"options": {
"livereload": "<%= connect.options.livereload %>"
}
手动配置端口
打开项目根目录的Gruntfile.js文件;
找到下面配置项,修改其中的port和livereload参数值为可用的端口(两个不能相等);
1
2
3
4
5
6
7
8
9"connect": {
"options": {
"port": 9000,
// change this to '0.0.0.0' to access the server from outside
"hostname": "localhost",
"livereload": 35729
},
//...
}修改 Task “watch” 内所有属性名为livereload的options的值如下:
1
2
3"options": {
"livereload": "<%= connect.options.livereload %>"
}