1. 生产环境Use the Power of Command Shells
$ sw_versProductName: Mac OS XProductVersion: 10.14.4BuildVersion: 18E227
$ node -vv10.14.1
$ npm -v6.4.1
cocos creator v2.0.8
2.1 基本用法
官方命令行发布文档[1]有介绍用法,其中build后面的默认参数在 ${projectPath}/settings/builder.json 配置。
/Applications/CocosCreator.app/Contents/MacOS/CocosCreator --path projectPath--build "platform=android;debug=true"
我们建立一个项目,创建shell脚本 ${projectPath}/tools/build/build.sh。
#!/bin/bash#author:lamyoung# build.sh/Applications/CocosCreator.app/Contents/MacOS/CocosCreator --path './../../' --build "platform=web-mobile;"
在终端修改build.sh为可执行文件。
$ cd ${projectPath}/tools/build/$ chmod +x ./build.sh
在终端执行build.sh,可以看到正在发布web版。
$ ./build.sh
2.2 传输参数构建
要使用同一个shell脚本构建发布不同平台,需要添加传输参数控制,我们可以使用getopts
#!/bin/bash#author:lamyoung#build.sh
your_target='web' #默认web平台your_debug=0 #默认debug关闭
while getopts "t:d" arg do case $arg in t) your_target=$OPTARG ;; d) your_debug=1 ;; esacdone
if [ !$your_debug ]then your_debug='debug=false'else your_debug='debug=true'fi
echo "target:$your_target"echo "$your_debug"
case $your_target in web) echo 'your target is web' /Applications/CocosCreator.app/Contents/MacOS/CocosCreator --path './../../' --build "platform=web-mobile;${your_debug};" ;; fb) echo 'your target is fb' /Applications/CocosCreator.app/Contents/MacOS/CocosCreator --path './../../' --build "platform=fb-instant-games;${your_debug};md5Cache=false" ;; *) echo '-t must be in [web/fb]' ;;esac
在终端调用 可以打包web-debug版
$ ./build.sh -t web -d
我们使用nodejs环境下的gulp接着构建我们打包好的项目,包括图片压缩,混淆等。在${projectPath}/tools/build/目录下初始化nodejs环境,安装gulp。
$ cd ${projectPath}/tools/build/$ npm init$ npm i gulp --save-dev
以web目标按步骤构建为例,创建build_web_gulpfile.js 在build.sh里加上对按步骤构建的调用。
# build.sh## ...省略代码
echo 'your target is web'/Applications/CocosCreator.app/Contents/MacOS/CocosCreator --path './../../' --build "platform=web-mobile;${your_debug};"gulp -f build_web_gulpfile.js #加上这一句
## ...省略代码
3.1 备份
先把之前打包的好的文件先备份,用到了nodejs的del库。
$ cd ${projectPath}/tools/build/$ npm i del --save-dev
//build_web_gulpfile.jsconst path = require('path');const folderP = path.resolve(__dirname, '../../');const del = require('del');const gulp = require('gulp'); //https://gulpjs.com/// 清理备份gulp.task('clean_backup', function (cb) { del.sync([`${folderP}/build/web-mobile_backup/`], { force: true }); cb()});
// 备份gulp.task('backup', function (cb) { gulp.src([`${folderP}/build/web-mobile/**`]) .pipe(gulp.dest(`${folderP}/build/web-mobile_backup/`)) .on("end", cb);});
3.2 读取不同目标的配置
打包发布会有不同的目标(如web,facebook),针对不同的目标加一个${projectPath}/tools/build/buildConfig.json文件作为打包参数的配置。
{ "web": { "texture": { "assets/Texture/common": { "speed": 4, "quality": [ 0.2, 0.3 ] } }, "javascript-obfuscator-options": { "compact": true, "controlFlowFlattening": true, "controlFlowFlatteningThreshold": 0.3, "deadCodeInjection": true, "deadCodeInjectionThreshold": 0.05, "identifierNamesGenerator": "hexadecimal", "rotateStringArray": true, "selfDefending": true, "stringArray": true, "stringArrayEncoding": "rc4", "stringArrayThreshold": 0.5, "seed": 7777, "debugProtection": true, "debugProtectionInterval": true, "disableConsoleOutput": true, "log": false } }, "fb": { "texture": { "assets/Texture/common": { "speed":7, "quality": [ 0.2, 0.3 ] } }, "javascript-obfuscator-options": { "compact": true, "controlFlowFlattening": true, "controlFlowFlatteningThreshold": 0.2, "deadCodeInjection": true, "deadCodeInjectionThreshold": 0.05, "identifierNamesGenerator": "hexadecimal", "rotateStringArray": true, "selfDefending": true, "stringArray": true, "stringArrayEncoding": "rc4", "stringArrayThreshold": 0.3, "seed": 66666, "debugProtection": true, "debugProtectionInterval": true, "disableConsoleOutput": true, "log": false } }}
添加读取配置的gulp任务。
const fs = require("fs");let build_config = {};//读取配置gulp.task('read_build_config', (cb) => { const data_build_config = fs.readFileSync(path.join('./', 'buildConfig.json')); build_config = JSON.parse(data_build_config.toString()).web; console.log('build_config', build_config); cb();})
3.3 混淆js代码
用到gulp-javascript-obfuscator,obfuscator参数参考[2]
$ npm i gulp-javascript-obfuscator --save-dev
build_config是上面读取的配置
//build_web_gulpfile.jsconst javascriptObfuscator = require("gulp-javascript-obfuscator");// 混淆gulp.task("javascriptObfuscator", function (cb) { gulp.src([`${folderP}/build/web-mobile/src/*.js`]) .pipe(javascriptObfuscator(build_config["javascript-obfuscator-options"] || {})) .pipe(gulp.dest(`${folderP}/build/web-mobile/src/`)) .on("end", cb);});
3.4 压缩图片
由于用引擎打包发布后文件名字是按照uuid映射命名,路径不好找,特别是使用到了自动图集[3]功能。在论坛上找到了一个构建资源图集信息插件[4],支持构建后输出图片路径,方便我们针对不同的图片压缩不同的参数。只需要把这个插件放在 ${projectPath}/packages 下,具体可参考插件使用的官方文档[5]。成功打包发布后为生成 ${folderP}/$buildtexture.json 。
这次我们使用gulp-imagemin[6] 和 imagemin-pngquant[7]来压缩图片。
$ cd ${projectPath}/tools/build/$ npm i gulp-imagemin --save-dev$ npm i imagemin-pngquant --save-dev
//build_web_gulpfile.jsconst imagemin = require('gulp-imagemin');const imageminPngquant = require('imagemin-pngquant');//压缩图片gulp.task('imagemin', (cb) => { // 同步读取 const data_buildtexture = fs.readFileSync(path.join(folderP, '$buildtexture.json')); const _buildtexture_config = JSON.parse(data_buildtexture.toString()); const _texture_config = build_config.texture || {}; const pack_files = {}; let total_count = 0; for (const key in _buildtexture_config) { if (_buildtexture_config.hasOwnProperty(key)) { const element = _buildtexture_config[key]; if (_texture_config[element.name]) { const targetPath = `${folderP}/build/web-mobile/res/raw-assets/**/${key}*.png`; if (!pack_files[element.name]) { pack_files[element.name] = []; total_count++; } pack_files[element.name].push(targetPath); } } } let cur_count = 0; for (const key in pack_files) { if (pack_files.hasOwnProperty(key)) { const element = pack_files[key]; console.log(`start.. ${key}`); const cfg = _texture_config[key]; console.log(cfg); gulp.src(element) .pipe(imagemin([ imagemin.gifsicle(), imagemin.jpegtran(), imagemin.optipng(), imagemin.svgo(), imageminPngquant(cfg) ], { verbose: true })) .pipe(gulp.dest(`${folderP}/build/web-mobile/res/raw-assets/`)) .on("end", () => { console.log(`end.. ${key}`); cur_count++; console.log(`progress ${cur_count}/${total_count}`); if (cur_count >= total_count) { cb(); } }); } }})
3.5 将所有任务链接在一起
gulp.task('default', gulp.series(gulp.parallel('read_build_config', 'clean_backup'), 'backup', gulp.parallel('imagemin', 'javascriptObfuscator')));
最后把构建完后的结果按照版本号保存。
# build.sh## ...省略代码
your_version=`date +%Y%m%d%H%M%S`echo 'your target is web'/Applications/CocosCreator.app/Contents/MacOS/CocosCreator --path './../../' --build "platform=web-mobile;${your_debug};"gulp -f build_web_gulpfile.jscd './../../build'zip -r "./web_${your_game_name}_${your_version}" './web-mobile'open ./
## ...省略代码