构建流程简介与常见错误处理
构建流程简介
Cocos Creator 3D 的构建流程,这里拆分为三大块:
a. 构建 setting.js(包含对资源和脚本的打包处理)
b. 打包模板文件
c. 打包引擎
目前构建后的文件夹路径是会在构建是选择的发布路径里生成一个以平台为前缀的文件夹,如果当前发布路径文件夹内有和平台同名的文件夹,就按顺序添加 _001
以此类推。
a.构建 setting.js
编辑器内打包项目都会生成一个 setting.js 的文件,里面记录项目相关的很多重要配置和资源信息,是引擎能够正确查找资源的一个索引文件。因而 setting.js 的构建是打包过程中的一项重要工作。
严格来说这个部分不仅仅是构建出一个 setting.js ,但是由于这个文件的生成需要在项目内的资源整理完毕之后才能完整的生成,所以将这部分的处理都归结于 构建 setting.js
,这一部分内容的构建时间通常会随着项目资源的增多而加长,主要可以拆分为资源的构建和脚本的构建。
构建资源
首先来介绍资源的打包过程。这一步骤内所指的对资源的打包是指除了脚本以外的资源文件,因为脚本是作为特殊文件来打包处理的。在打包资源阶段,编辑器会先汇总当前参与构建的场景以及所有在 resources
目录下的资源,每个资源的打包都会经过引擎的反序列化,查找出依赖资源再递归进行资源的打包。在反序列化之前会先配置整个项目的脚本环境,也就是加载所有的非插件项目脚本。因为脚本的加载正确与否会直接影响到反序列化的进行,因而如果脚本编写的不合法加载失败会直接导致构建失败。如果在反序列化过程中发现有依赖的资源丢失会发出警告,但会继续进行构建。这里的警告并不意味着问题不需要解决,如果资源丢失不解决,是难于保证构建后的内容不出问题的。
通过上面的介绍,我们知道只有在 resources
目录下的资源以及参与构建场景明确引用依赖的资源才会被打包到最终的构建文件夹内。所以如果在脚本内使用了某个资源但这个资源没有被场景引用也没有放在 resources
目录下,之后加载就会出现 404 了。
资源在打包过程中,在反序列化后会进行重新的压缩序列化,减小打包之后的包体。对 texture 资源的序列化文件会全部打包成一个 json 文件,其他序列化文件会根据构建配置参数来决定是否分包处理。打包之后,所有的序列化文件都会放置在构建后目录的 res/import
目录下,所有的资源源文件将会放置在 res/raw-assets
目录下。
资源打包过程中也会不断的收集参与资源构建的资源 uuid ,最终会整理写进 setting.js 。setting.js 会被写入在构建后文件夹的 src
目录下,生成之前将会根据是否构建调试模式来决定是否对文件内的 uuid 做压缩处理,所有使用到的 uuid 会进行整理,将出现 2 次 以上的存储进 uuids 数组内,之前使用 uuid 的位置替换为索引。
如果勾选了 md5Cache 选项,会在生成 setting.js 之前,对现有的所有资源文件加上 md5 时间戳。同时会在 setting.js 内放置整理后的 md5AssetsMap 。md5AssetsMap 是一个数组,以 [uuid_1, md5_1, uuid_2, md5_2, …] 的格式存储的,其中 uuid_1 如果是个简单数字说明存储的是 uuids 数组内的 uuid 索引。
构建脚本
编辑器内对脚本的构建是分为两类的,插件脚本和非插件脚本。插件脚本会直接把源文件按照原来的目录结构拷到构建后文件夹的 src
目录下,所以插件脚本是不支持任何需要编译的脚本形式的比如 ts 或者是使用 es6 写法的 js。插件脚本的资源信息则会写进 settings 里的 jsList 数组内。
非插件脚本将会全部打包成 project.js (调试模式下是 project.dev.js ),放在对应的 src 目录下。
在资源和脚本构建完成后,编辑器会再整合一些项目设置与构建配置的参数内容,生成最终版的 setting.js 。这份 setting.js 是引擎运行时获取项目信息的索引所在,具体对 setting 脚本内容的使用方式可以参见打包出来的 main.js ,只有这份内容信息完整正确才能正确的加载项目资源运行场景。
b. 打包模板文件
这部分的流程内容对每个平台来说是固定的,通常也不会花费太多时间, 主要就是根据不同的构建配置参数写入模板生成文件到构建后的文件夹内。除此之外就是用户模板文件的拷贝了,用户模板文件构建不会去做任何编译处理操作,主要就是把用户模板的对应平台内的文件夹按照原有的路径一比一的拷贝到打包后的文件夹呢覆盖重名文件。
c. 打包引擎文件
引擎打包的主要步骤是
获取设置里排除的引擎模块信息;
检查缓存中的引擎版本与当前需要编译的引擎是否一致,内容一致无法再次编译直接拷贝;
根据引擎接口,执行打包引擎的 gulp 任务,之后拷贝编译后的 js 文件,并保存模块数据与引擎版本信息用于下次比对;
由于引擎的脚本文件比较多,打包引擎会比较慢。所以在每次打包之后,会缓存打包后的引擎脚本和引擎打包时的对应模块设置,这样如果之后有同一平台相同配置构建就会复用之前打包的引擎文件,如果不希望复用可以勾选构建配置面板的 强制更新引擎
。
打包的引擎的过程中会根据配置的参数是否为调试模式来决定是否压缩引擎文件,同时会根据当前项目设置的引擎模块来选择剔除某些不需要的模块。
关于引擎文件的复用规则,这里有必要阐述下:打包好的引擎文件将会放置在引擎目录的 bin/.cache/.editor-cache
文件夹下, 按照会影响引擎编译的参数生成的 hash 值存放。
engine-folder
|--bin
|--.cache
|--.editor-cache
|--cache-config.json
|-- 1dc4a547f9...63a43bb8965
...
其中的 cache-config 存储的是外部 hash 文件名作为 key , 对应的构建参数作为 value 的对象格式存储。每个 hash 值对应的参数就是会影响引擎复用的参数了,只要相关的引擎构建参数发生更改,就会重新编译引擎。
- debug: 是否打开调试模式
- excludes: 引擎模块设置
- isQQPlay:是否是 QQPlay 平台
- isWeChatGame:是否是微信小游戏平台
- isWeChatSubdomain:是否是微信子域平台
- sourceMaps:是否开启 sourcemap
- engineMtime:引擎 bin/.cache/dev/quick_compile.js 的修改时间
常见错误及处理
构建的整个进程是在一个单独的 worker 内的,所以如果想要查看构建过程的 log 信息或者查看出现报错时完整的调用栈,可以在主菜单的 开发者 -> 打开构建调试工具
里打开。构件时其实会输出很多的 log 信息,但是为了不干扰用户只有错误和重要信息会被打印到编辑器的控制台,调试工具里的信息才是最完整的。
有必要说明的是,在构建之前请先确保参与构建的场景是可以正常预览的。一些场景的资源丢失或者其他脚本问题,是在预览阶段就能暴露出来的。在保证预览正常的情况下构建能更好的节约时间以及排查问题。
资源丢失
资源丢失主要指的是,改资源在 library 里面不存在,在前面的构建流程里介绍过,资源的构建会经过反序列查找依赖,而最经常出现的问题就是所依赖的资源在项目迭代过程中被不小心删除而导致资源丢失。这些资源的丢失可能平时并没有注意到,但一旦构建都会暴露出来的。另一种资源丢失,就是资源没有导入成功,但是在脚本里面写了加载改资源的逻辑,这种情况通常在资源放进去后就会报错。
这时候,请复制报资源丢失信息里的 uuid
去资源管理器里面查找对应的资源,查看该资源依赖的资源是否都正常。
脚本资源加载报错
在前面介绍资源打包时有提到过,构建需要配置脚本环境,因而如果此时抛出的错误是脚本的,请参考报错内容对脚本进行更改。如果不清楚是哪个脚本的报错,可以找到报错信息调用栈内对应脚本的 uuid ,在资源管理器内查找定位。
引擎编译失败
通常不会出现此问题,如果遇到引擎编译失败,请带上你的报错信息截图在论坛或者其他反馈渠道告知我们。
其他报错
如果遇到其他无法自行解决的构建报错信息,请带上你的构建配置截图、构建调试工具里的 log 信息以及 demo 在论坛提问。