马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?注册帐号
x
运行游戏使用的命令是gulp run,agar.io-clones使用了nodejs开发,gulp是基于nodejs的一个工具,它能够批量的做一些文件操作。gulp run意思是执行目录下gulpfile.js下的run任务,那么源码中使用了gulp的哪些功能呢?这篇文章将会做个简单介绍。
知乎@罗培羽
gulp能自动化地完成 javascript/coffee/sass/less/html/image/css 等文件的的测试、检查、合并、压缩、格式化、浏览器自动刷新、部署文件生成,并检测文件变化。在实现上,gulp鉴了Unix操作系统的管道(pipe)思想,前一级的输出,直接变成后一级的输入。
关于gulp入门,可以参考下面的文章:
http://www.ydcss.com/archives/18
http://www.gulpjs.com.cn/docs/getting-started/
一个最简单的示例
要使用gulp根据,当然得先安装它,有两种方式安装,对应于不同的命令参数。
全局安装 gulp: npm install --global gulp
作为项目的开发依赖(devDependencies)安装:npm install --save-dev gulp
现在新建一个目录并创建一个名为 gulpfile.js 的文件,在里面编写如下代码
[] 纯文本查看 复制代码 var gulp = require('gulp');
gulp.task('default', function() {
// 将你的默认的任务代码放在这
});
在目录下执行gulp,此时程序会搜寻目录下gulpfile.js文件中的默认(default)任务,也就是上面代码中“// 将你的默认的任务代码放在这”处的代码去执行。“gulp run”即表示执行名为run的任务,相关代码可以在项目文件夹下的gulpfile.js中看到。相关代码如下
[] 纯文本查看 复制代码 gulp.task('run', ['build'], function () {
nodemon({
delay: 10,
script: './server/server.js',
cwd: "./bin/",
args: ["config.json"],
ext: 'html js css'
})
.on('restart', function () {
util.log('server restarted!');
});
});
代码解析
要看懂上面的代码,必须要了解gulp的一些API,知道“nodemon”等单词到底是什么意思,实现什么功能,gulp的api可以参考下面的文章:
http://www.ydcss.com/archives/424
依赖
上面代码中的“gulp.task('run', ['build'], function (){}”意为run依赖于build,当执行gulp run时,程序会先执行build任务,再执行run任务。
nodemon
先看看nodemon,详细的解释可以参考https://www.npmjs.com/package/gulp-nodemon。
nodemon 是一个工具,用于项目代码发生变化时可以自动重启,nodemon 本意时检测项目变化的,对项目做监控的。重启只是它的一个功能。在上面的代码中,相当于执行./server/server.js这个文件。而这个文件其实是build任务中生成的。
build任务
接下来看看build任务是什么样子的,会发现build任务依赖于build-client、build-server、test、todo这4个任务,也就是说,需要按顺序先执行这4个任务,才会执行build。此时我们会发现,代码的执行流程是build-client、build-server、test、todo、run
[] 纯文本查看 复制代码 gulp.task('build', ['build-client', 'build-server', 'test', 'todo']);
build-client任务
build-client处理了客户端代码的创建,它用到了uglify、webpack和babel 。
其中uglify表示压缩javascript文件,减小文件大小(参见http://www.ydcss.com/archives/54)
webpack表示模块打包,它能帮我们把本来需要在服务端运行的JS代码,通过模块的引用和依赖打包成前端可用的静态文件(参考 http://www.cnblogs.com/xz1024/p/5853794.html)
babel是一个JavaScript转换编译器,它可以将ES6(下一代JavaScript规范,添加了一些新的特性和语法)转换成ES5(可以在浏览器中运行的代码)。这就意味你可以在一些暂时还不支持某些ES6特性的浏览器引擎中,使用ES6的这些特性。比如说,class和箭头方法。
pipe表示管道,下面的代码是指将源文件(.src)“src/client/js/app.js”通过uglify方法压缩,然后将压缩后的结果通过webpack打包,然后通过babel做兼容性,最后通过将文件存入dest指定的目录下“bin/client/js/”
[] 纯文本查看 复制代码 gulp.task('build-client', ['lint', 'move-client'], function () {
return gulp.src(['src/client/js/app.js'])
.pipe(uglify())
.pipe(webpack(require('./webpack.config.js')))
.pipe(babel({
presets: [
['es2015', { 'modules': false }]
]
}))
.pipe(gulp.dest('bin/client/js/'));
});
webpack()方法的参数是“require('./webpack.config.js') ”“ ./webpack.config.js”,该文件的内容如下,它是打包的配置文件。
[] 纯文本查看 复制代码 module.exports = {
entry: "./src/client/js/app.js",
output: {
path: require("path").resolve("./src/bin/client/js"),
library: "app",
filename: "app.js"
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel'
}
]
}
};
“build-client”依赖于“lint”和“move-client”,先要完成这两个任务,程序才会执行“build-client”任务。
lint任务
“lint”任务如下所示,它使用了jshint方法。jshint是用来检测javascript的语法错误的。如果有错误,就报告fail。
[] 纯文本查看 复制代码 gulp.task('lint', function () {
return gulp.src(['**/*.js', '!node_modules/**/*.js', '!bin/**/*.js'])
.pipe(jshint({
esnext: true
}))
.pipe(jshint.reporter('default', { verbose: true}))
.pipe(jshint.reporter('fail'));
});
move-client任务
“build-client”还依赖于“move-client”代码如下,它只是移动一些文件
[] 纯文本查看 复制代码 gulp.task('move-client', function () {
return gulp.src(['src/client/**/*.*', '!client/js/*.js'])
.pipe(gulp.dest('./bin/client/'));
});
build-server任务
build-server任务比较简单,它也是复制下文件
[] 纯文本查看 复制代码 gulp.task('build-server', ['lint'], function () {
return gulp.src(['src/server/**/*.*', 'src/server/**/*.js'])
.pipe(babel())
.pipe(gulp.dest('bin/server/'));
});
test任务
build任务依赖于build-client、build-server、test和todo任务,在建了客户端和服务端文件后,自然需要对它测试一下,test任务调用了mocha方法,它是一个测试方法。
[] 纯文本查看 复制代码 gulp.task('test', ['lint'], function () {
gulp.src(['test/**/*.js'])
.pipe(mocha());
});
todo任务
todo任务调用了todo方法,该方法会收集符合“src/**/*js”匹配符的文件信息,生成一个名为TODO.md的文件。
[] 纯文本查看 复制代码 gulp.task('todo', ['lint'], function() {
gulp.src('src/**/*.js')
.pipe(todo())
.pipe(gulp.dest('./'));
});
生成的TODO.md如下图所示。
由于实际运行的文件在是bin/目录下,如果修改了源文件,需要重新执行gulp run才能生效。
还是放个广告吧,笔者出版的一本书《网络游戏实战》充分的讲解怎样开发一款网络游戏,特别对网络框架设计、网络协议、数据处理等方面都有详细的描述,相信会是一本好书的。
|