Laya 命令行layacmd、资源版本管理

参考
layacmd
资源版本管理

一、layacmd

注意,官方在2017.12.13发帖子(更改layacmd名字为layaair-cmd)说,由于npm账号问题导致无法修改之前的layacmd文件,所以现将layacmd名字改为layaair-cmd。
修改之后的文档在官网的地址
在npmjs的地址
相关的帮助文档也变成了layaair-cmd,当然安装方式也由之前的npm install layacmd -g,变成npm install layaair-cmd -g

layaair-cmd的大部分子命令都需要当前工作目录下包含layaair项目,少数命令可以手动指定输入目录,如guetzl,atlas命令则是即可以直接$ layaair-cmd atlas,也可以指定输入目录。

1.编译
layacmd compile
2.发布
layacmd publish -n 1.0.1
3.导出UI
layacmd ui -c -a
4.资源版本控制
layacmd resourceVersion -i res -o . -n 1.0.0
5.guetzli
layacmd guetzli -i src
该命令不需要当前目录包含layaair项目,取而代之的是,你需要指定输入目录。压缩成功后,源文件会被修改。压缩失败则源文件保持不变。
guetzli的压缩过程很慢,而且占用资源大,所以可能要等待些时间。最好在资源版本控制生成的文件夹中使用guetzli压缩,这可以保证不会重复压缩一张图。
注意这里只有-i,没有-o,也就是直接改了源文件,不如用Gulp脚本来运行guetzli更方便
6.本地服务器
layacmd open 9000 -s
9000是端口号,-s 表示 don't open browser
这个很明显,用的是anywhere

二、资源版本管理

资源版本控制用于为资源生成版本。版本号默认从数字1000开始递增,如果传入--versionName参数,则使用用户指定的版本名称。下次建立建立版本时如果没有再次指定--name,版本号为1002,因为每次生成版本,资源版本控制内部版本计数器都会递增。
在建立版本时,相对于上次版本建立,修改了的文件或者新增的文件会被记录在新版本中。如果没有新增文件或者没有修改文件,不会有新版本生成。
在最终使用资源时,不允许使用上层相对路径,即路径中包含“..”。

$ layacmd resourceVersion -h
  Usage: layacmd-resourceVersion [options]
  Options:
    -h, --help                       output usage information
    -V, --version                    output the version number
    -i --input <input>               资源目录
    -o --output <output>             导出目录
    -n --versionName <version name>  版本名称,默认是从1000开始递增的数字

该命令不需要当前目录包含layaair项目,取而代之的是,你需要指定输入目录。
比如:

layacmd resourceVersion -i res -o . -n 1.0.0

这里-i代表资源路径,-o . 代表版本资源输出路径为当前路径,当然开发者也可以自定义输出路径,比如定义路径为version文件夹等等,-n 1.0.0初始化版本为1.0.0。
参考资源版本管理问题官方回复:

Q:这个 -i res 的意思是只处理res目录吗?如果res目录之外还有目录跟js文件需要打版本那要怎么搞呢?
A:一般一个项目只会针对一个资源文件夹,很少出现2个完全分离的资源文件夹,所以我们的命令行目前也只能针对一个资源文件夹做资源版本控制,-i res ,,,res可以为任意路径!

1.资源版本
名为1000、1001、1002的文件夹是默认资源版本名称,里面保存的是对应版本被修改了的资源。
2.record记录文件
.record在Unix-like系统中是隐藏文件。这个文件保存最近的版本建立信息,资源版本控制由此来判定建立新版本时哪些文件被修改。这个文件不能被删除,如果这个文件丢失,之前建立的版本就会丢失,相当于重新开始建立版本。
3.manifest.json

{
    "res1": "1000",
    "res2": "1000",
    "res3": "1002",
    "sub\\res3": "1000",
    "sub\\res4": "1000"
}

从中得到每个资源的最新版本号,从这些文件夹读取manifest.json对应的版本资源(资源根目录/版本号/相对文件路径)
4.资源版本切换
由于manifest.json保存各版本的文件版本号。所以只需要保留历史manifest.json即可使用对应版本的资源。

三、实践
package
{
    import laya.net.Loader;
    import laya.net.ResourceVersion;
    import laya.utils.Handler;
    public class Main
    {
        private var configUrl:String ="manifest.json?"+Math.random();;
        public function Main()
        {
              Laya.init(500,500);
              ResourceVersion.enable(configUrl,Handler.create(this,this.completeHandler));
        }
        private function completeHandler(e:Object):void
        {
           var obj:Object = Laya.loader.getRes(configUrl);
           var data:Array =[
               {"url":"res/sound/a.mp3","type":Loader.BUFFER},
               {"url":"res/data/data.data","type":Loader.TEXT}
           ]
           Laya.loader.load(data,Handler.create(this,resComplete));
        }
        private function resComplete():void
        {
        }
    }
}

按照资源版本管理,如果我们修改了文件,但一直用
layacmd resourceVersion -i res -o . -n 1.0.0来打包,其实mainfest.json是不会变的。当然新增文件,会添加新的一行,版本号还是1.0.0

0 new files    (+)
0 deletions    (-)
1 modifications(*)
5 no changes   (=)

从上面的log中也能看出,这个工具实际上在对比文件变化,记录到mainfest.jon中,标清每一个文件要去1.0.0里取,还是1.0.1里取。

四、问题:

1.图集和未打包图片不在一个路径下
IDE的资源中,有一部分是不打包的,按照默认设置,不打包的图片直接导到bin目录下,而打包的图集资源是在res/atlas下面。这样上面讲的资源版本管理,如果只针对res目录,那么不打包的资源就不在控制范围内了。

解决办法就是把未打包图片,也放到res下面。


Paste_Image.png

这样会出现运行过程中加载不到这些外部图片,因为basePath默认指向根目录。解决办法就是改basePath。具体参考Laya Loader 图集 图片

var addPath:string = Laya.URL.basePath += "res/";
Laya.URL.rootPath=Laya.URL.basePath = addPath;

2.在哪里做资源版本?
Q:资源管理,是放在bin下,在发布release时一并导出。还是发完release后,再去release下的资源目录中做资源管理呢?
A:LAYA IDE自带的发布功能,每次都需要一个新的版本号,比如1.0.4。那么在1.0.4资源目录中,是没办法找到之前的mainfest和资源的,除非去1.0.3里,复制过来。然后再运行layacmd。另外,还要添加代码

var configUrl:string ="manifest.json?"+Math.random();
Laya.ResourceVersion.enable(configUrl,Handler.create(this,this.completeHandler));

虽然可以在debug版本中通过标记变量判断是release版本才执行这段代码。
综上,我选择了在debug中就做资源版本
3.直接在res目录下运行layacmd resourceVersion -i . -o . -n 1.0.0,生成的mainfest.json中都是这样的:"res\/1.0.0\/res\/atlas\/comp.json": "1.0.1",.然后ResourceVersion.as中这段代码就会出问题

        /**
         * 为加载路径添加版本前缀。
         * @param   originURL   源路径。
         * @return 格式化后的新路径。
         */
        public static function addVersionPrefix(originURL:String):String {
            if (manifest && manifest[originURL])
                return manifest[originURL] + "/" + originURL;
            return originURL;
        }

因为传进来的参数originURL前面并没有带res,所以if (manifest && manifest[originURL])判断 失效。于是我悲剧地重写这个方法:

Laya.ResourceVersion.addVersionPrefix=function(originURL){
    originURL = "res/"+originURL;
    if (Laya.ResourceVersion.manifest && Laya.ResourceVersion.manifest[originURL])
        return Laya.ResourceVersion.manifest[originURL]+"/"+originURL;
    return originURL;
}

ok,一切正常了。然而事情并没完,当我修改文件,去打1.0.1时,由于还是在res内打包,就出现把之前的1.0.0也打包到1.0.1里……

Paste_Image.png

所以我们不能在res目录内用命令来分资源版本。
4.重新回到bin目录下,使用命令:
layacmd resourceVersion -i res -o . -n 1.0.0
manifes.json:
"res\/atlas\/.rec": "1.0.0"
发现1.0.0下面已经有res目录,所以basePath不需要再添加res了。
那么addVersionPrefix还要不要重写呢,测试了下,还是需要的。因为IDE中未打包资源的skin并未携带res前缀,虽然其它资源我们可以手动上res前缀,比如

        function loadSound():void
        {
            var obj:Object = Laya.loader.getRes("res/sound/a.mp3");
        }

         function resComplete():void
        {
            Laya.loader.load([{ url: "res/atlas/comp.json", 
                  type: Loader.ATLAS }], Handler.create(this, this.onLoaded));
        }

重写addVersionPrefix方法就相当于给所有经过版本控制的资源,都添加了res前缀,这样不管是图集,音乐,还是外部加载图片,都不需要再添加res前缀了
5.最后根据debug,release来分策略加载

private loadByResVersion() {
    var bgInfo = window["bgInfo"];
    if (!bgInfo["debug"]) {
        //重写版本控制中路径方法
        Laya.ResourceVersion.addVersionPrefix = function (originURL) {
            originURL = "res/" + originURL;
            if (Laya.ResourceVersion.manifest && Laya.ResourceVersion.manifest[originURL]) {
                return Laya.ResourceVersion.manifest[originURL] + "/" + originURL;
            }
            return originURL;
        }
        var configUrl: string = "manifest.json?" + Math.random();
        Laya.ResourceVersion.enable(configUrl, Laya.Handler.create(this, this.beginGameLoad));
    } else {
        var addPath: string = Laya.URL.basePath += "res/";
        Laya.URL.rootPath = Laya.URL.basePath = addPath;
        this.beginGameLoad();
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容