天天看点

Use shell in cocos creator1. 生产环境2. 使用命令行发布3. 按步骤构建-gulp4. 按版本保存

Use the Power of Command Shells

1. 生产环境

$ sw_vers
ProductName:    Mac OS X
ProductVersion:    10.14.4
BuildVersion:    18E227

$ node -v
v10.14.1

$ npm -v
6.4.1           

复制

cocos creator v2.0.8           

复制

2. 使用命令行发布

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
        ;;
    esac
done

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           

复制

3. 按步骤构建-gulp

我们使用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.js
const 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.js
const 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.js
const 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')));           

复制

4. 按版本保存

最后把构建完后的结果按照版本号保存。

# 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.js
cd './../../build'
zip -r "./web_${your_game_name}_${your_version}"  './web-mobile'
open ./

## ...省略代码           

复制

项目源码地址[8]

References

[1]

官方命令行发布文档: https://docs.cocos.com/creator/manual/zh/publish/publish-in-command-line.html

[2]

obfuscator参数参考: https://github.com/javascript-obfuscator/javascript-obfuscator#javascript-obfuscator-options

[3]

自动图集: https://docs.cocos.com/creator/manual/zh/asset-workflow/auto-atlas.htmls

[4]

构建资源图片信息插件: https://forum.cocos.com/t/topic/76554

[5]

使用插件的官方文档: https://docs.cocos.com/creator/manual/zh/extension/

[6]

gulp-imagemin: https://github.com/sindresorhus/gulp-imagemin

[7]

imagemin-pngquant: https://github.com/imagemin/imagemin-pngquant

[8]

项目源码地址: https://github.com/baiyuwubing/cocos_shell