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                资源目录
    -o --output              导出目录
    -n --versionName   版本名称,默认是从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下面。


Laya 命令行layacmd、资源版本管理_第1张图片
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里……

Laya 命令行layacmd、资源版本管理_第2张图片
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();
    }
}

你可能感兴趣的:(Laya 命令行layacmd、资源版本管理)