小游戏,bundle过多导致打包过慢

现在的设计每个关卡一个bundle,80多个bundle需要15分钟。如何只打制定的bundle

可以自己写个插件,定制一下阔阔西的构建流程只对对应的资源打包。

目前我也有这个需求。但是你让我写。没那么多时间去写插件跟了解那些玩意。这个功能本应该就是官方需要支持的。如果你搞出来了,我想白嫖一下 :rofl:

mark一下

白嫖到了麻烦告诉一声

白嫖到了麻烦告诉一声

目前的解决方案是,首次正常打包。新增bundle后,用脚本修改bundle的mate文件,打开需要打包关卡的bundle,其他关闭掉,然后开始打包,最后还原mate文件修改

如果是打包web-mobile
image
找到这个文件,把上次打包的这个文件和新打包的这个文件合并。主要是合并bundleVers 这个字段
image
修改完后把新打的包直接覆盖到上次的打包的目录。
如果是打字节的包,除了要合并setting文件。还需要合并ccRequire.js文件
image
思路是一样的
image
主要是做个bundle脚本的映射

参考代码

    #如果是web 从远程下载Index.html , 获取setting.xxx.js 即 setingFilename

    #修改文件
    tt = CocosReBuild()
    
    tt.modifyBundle(levels)

    #构建
    os.system(buildCommond)

    tt.modifyBundle([],True)
    
    tt.doing(platform,setingFilename)

    #移除临时文件
    if platform == "webTest" or platform == "web":
        #远程下载的index.html,用来找setting.xxx.js文件
        os.remove(os.path.join(project_root,'build',setingFilename))
        os.remove(downloadIndexPath)

    #上传 字节是上传remote目录,web是这个构建目录上传
    print("upload...")
    os.system(uploadCommond)

    if platform == "byte":
        shutil.rmtree(dirpath)
        tempDir = os.path.join(project_root,'build',"bytedance_Temp")
        byteDir = os.path.join(project_root,'build',"bytedance")
        if os.path.exists(tempDir):
            shutil.rmtree(tempDir)
        shutil.copytree(byteDir, tempDir)

import ast
import json
import os
import re
import glob
import shutil
import demjson
my_path = os.path.abspath(__file__)
project_root = os.path.abspath(os.path.dirname(os.path.dirname(my_path)))
class CocosReBuild:
    def doing(self,platform,setingFilename):
        #重写setting文件
        if platform == "webTest" or platform == "web":
            settingroot1 = os.path.join(project_root,"build","web-mobile","src")
            settingpath1 = self.getSetingFilePath(settingroot1)
            with open(settingpath1, "r",encoding='utf-8') as f:
                text = f.read()
            f.close()
            pattern = re.compile(r'=(.*?);')
            match = pattern.search(text)
            json_data1 = {}
            if match:
                matched_text = match.group(1)
                json_data1 = demjson.decode(matched_text)
            else:
                raise NameError("读取setting file 错误")

            settingpath2 = os.path.join(project_root,"build",setingFilename)
            with open(settingpath2, "r",encoding='utf-8') as f:
                text = f.read()
            f.close()
            pattern = re.compile(r'=(.*?);')
            match = pattern.search(text)

            if match:
                matched_text = match.group(1)
                json_data = demjson.decode(matched_text)
                if "bundleVers" in json_data1:
                    for key in json_data1["bundleVers"]:
                        json_data["bundleVers"][key] = json_data1["bundleVers"][key]

                javascript_string = json.dumps(json_data, separators=(',', ':'))
                javascript_string = "window._CCSettings="+javascript_string + ";"

                with open(settingpath1, "w") as f:
                    f.write(javascript_string)
                f.close()
            else:
                raise NameError("读取setting file 错误")
                
        elif platform == "byte":
            self.modifySetting1()
            buildwebdir1 = os.path.join(project_root,"build","bytedance","src")
            buildwebdir2 = os.path.join(project_root,"build","bytedance_Temp","src")
            for src_dir, dirs, files in os.walk(buildwebdir2):
                dst_dir = src_dir.replace(buildwebdir2, buildwebdir1, 1)
                if not os.path.exists(dst_dir):
                    os.makedirs(dst_dir)
                for file_ in files:
                    src_file = os.path.join(src_dir, file_)
                    dst_file = os.path.join(dst_dir, file_)
                    if os.path.exists(dst_file):
                        # skip file if it already exists
                        print("skip file if it already exists:" , file_)
                        continue
                    shutil.copy2(src_file, dst_file)
                    print("cp %s -> %s" %(src_file, dst_file))

       
    def modifyBundle(self,remainLevel,allTrue=False):
        localBundle = os.path.join(project_root,"assets","AssetsPackage","Level")
        files = [f for f in glob.glob(os.path.join(localBundle, "*.meta"))]
        for file in files:
            isBundle = False
            for f in remainLevel:
                if os.path.basename(file) == "Lv"+str(f)+".meta":
                    isBundle = True
                    break
            
            with open(file, "r",encoding='utf-8') as f:
                text = f.read()
            f.close()

            if allTrue:
                isBundle = True

            data = json.loads(text)
            data["isBundle"] = isBundle

            json_string = json.dumps(data)
            with open(file, "w") as f:
                f.write(json_string)
        f.close()

    def modifySetting1(self):
        settingroot1 = os.path.join(project_root,"build","bytedance","src","settings.js")
        with open(settingroot1, "r",encoding='utf-8') as f:
            text = f.read()
        f.close()
        # 正则表达式
        pattern = re.compile(r'=(.*?);')
        # 匹配
        match = pattern.search(text)
        # 如果有匹配,取出匹配到的字符串
        json_data1 = {}
        if match:
            matched_text = match.group(1)
            json_data1 = demjson.decode(matched_text)

        settingroot2 = os.path.join(project_root,"build","bytedance_Temp","src","settings.js")
        with open(settingroot2, "r",encoding='utf-8') as f:
            text = f.read()
        f.close()

        # 正则表达式
        pattern = re.compile(r'=(.*?);')
        # 匹配
        match = pattern.search(text)
        # 如果有匹配,取出匹配到的字符串

        if match:
            matched_text = match.group(1)
            json_data2 = demjson.decode(matched_text)

            if not "bundleVers" in json_data1:
                json_data1["bundleVers"] = {}

            for key in json_data2["bundleVers"]:
                if key not in json_data1["bundleVers"]:
                    json_data1["bundleVers"][key] = json_data2["bundleVers"][key]
        
            if not "remoteBundles" in json_data1:
                json_data1["remoteBundles"] = []

            for key in json_data2["remoteBundles"]:
                if key not in json_data1["remoteBundles"]:
                    json_data1["remoteBundles"].append(key)

            javascript_string = json.dumps(json_data1, separators=(',', ':'))
            javascript_string = "window._CCSettings="+javascript_string + ";"

            with open(settingroot1, "w") as f:
                f.write(javascript_string)
            f.close()

        #处理ccRequire.js
        requirePath = os.path.join(project_root,"build","bytedance","ccRequire.js")
        lines = []
        with open(requirePath, "r",encoding='utf-8') as f:
            lines = f.readlines()
        f.close()
        
        for key in json_data2["remoteBundles"]:
            bundleName = key
            strs= "'src/scripts/%s/index.js' () { return require('src/scripts/%s/index.js') },\n" %(bundleName,bundleName)
            lines.insert(1,strs)
        content = ""
        for key in lines:
            content = content + key

        with open(requirePath, "w") as f:
            f.write(content)
        f.close()

web 平台我是从远程仓库下载到 build目录了,所以这里代码路径 settingpath2 = os.path.join(project_root,“build”,setingFilename),字节的我是字节新建了一个_Temp目录用来做上一个打包目录和当前目录的合并

我超,神!今天就去试试!