找回密码
 注册帐号

扫一扫,访问微社区

碧俐千仞 《球球大作战》源码解析——(3)gulp工具

3
回复
2308
查看
[ 复制链接 ]
排名
19945
昨日变化

43

主题

224

帖子

905

积分

Rank: 9Rank: 9Rank: 9

UID
53741
好友
40
蛮牛币
2618
威望
0
注册时间
2014-11-6
在线时间
222 小时
最后登录
2020-1-27

专栏作家

2017-5-7 23:39:53 显示全部楼层 阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

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如下图所示。
球球大作战 源码解析34560.png


由于实际运行的文件在是bin/目录下,如果修改了源文件,需要重新执行gulp run才能生效。


还是放个广告吧,笔者出版的一本书《网络游戏实战》充分的讲解怎样开发一款网络游戏,特别对网络框架设计、网络协议、数据处理等方面都有详细的描述,相信会是一本好书的。
球球大作战 源码解析34701.png





回复

使用道具 举报

7日久生情
1742/5000
排名
1823
昨日变化

0

主题

385

帖子

1742

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
181859
好友
0
蛮牛币
2799
威望
0
注册时间
2016-11-7
在线时间
629 小时
最后登录
2021-3-26
2017-5-8 08:22:01 显示全部楼层
顶瓜瓜,我勒个去。。。。。。。。。。。。。。。
回复

使用道具 举报

7日久生情
4315/5000
排名
1022
昨日变化

0

主题

2070

帖子

4315

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
94526
好友
0
蛮牛币
2999
威望
0
注册时间
2015-4-22
在线时间
1181 小时
最后登录
2021-1-25
2017-5-9 09:11:42 显示全部楼层
感谢楼主分享
回复

使用道具 举报

7日久生情
2229/5000
排名
20608
昨日变化

2

主题

1840

帖子

2229

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
185807
好友
0
蛮牛币
2903
威望
0
注册时间
2016-11-22
在线时间
361 小时
最后登录
2021-3-19
2017-5-22 16:54:14 显示全部楼层
赞,学习了,谢谢分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

关注游戏蛮牛公众号送vip