【微信小游戏】文件系统,远程加载资源打破4M限制
一、前提
微信小游戏,对游戏包体的大小有严格是限制,上传文件大小<4M,但是本地缓存文件有50M空间,也就是说我们可以将一些资源放到网上,然后缓存到本地。
二、官方概念
文件系统
文件系统是小程序提供的一套以小程序和用户维度隔离的存储以及一套相应的管理接口。通过 wx.getFileSystemManager() 可以获取到全局唯一的文件系统管理器,所有文件系统的管理操作通过 FileSystemManager 来调用。
文件主要分为两大类:
- 代码包文件:代码包文件指的是在项目目录中添加的文件。
- 本地文件:通过调用接口本地产生,或通过网络下载下来,存储到本地的文件。
其中本地文件又分为三种:
- 本地临时文件:临时产生,随时会被回收的文件。不限制存储大小。
- 本地缓存文件:小程序通过接口把本地临时文件缓存后产生的文件,不能自定义目录和文件名。除非用户主动删除小程序,否则不会被删除。跟本地用户文件共计最多可存储 50MB 文件。
- 本地用户文件:小程序通过接口把本地临时文件缓存后产生的文件,允许自定义目录和文件名。除非用户主动删除小程序,否则不会被删除。跟本地用户文件共计最多可存储 50MB 文件。
代码包文件
由于代码包文件大小限制,代码包文件适用于放置首次加载时需要的文件,对于内容较大或需要动态替换的文件,不推荐用添加到代码包中,推荐在小游戏启动之后再用下载接口下载到本地。
访问代码包文件
代码包文件的访问方式是从项目根目录开始写文件路径,不支持相对路径的写法。
修改代码包文件
代码包内的文件无法在运行后动态修改或删除,修改代码包文件需要重新发布版本。
本地文件
本地文件指的是小程序被用户添加到手机后,会有一块独立的文件存储区域,以用户维度隔离。即同一台手机,每个微信用户不能访问到其他登录用户的文件,同一个用户不同 appId 之间的文件也不能互相访问。
本地文件的文件路径均为以下格式:
{{协议名}}://文件路径
其中,协议名在 iOS/Android 客户端为
"wxfile"
,在开发者工具上为"http"
,开发者无需关注这个差异,也不应在代码中去硬编码完整文件路径。
本地临时文件
本地临时文件只能通过调用特定接口产生,不能直接写入内容。本地临时文件产生后,仅在当前生命周期内有效,重启之后即不可用。因此,不可把本地临时文件路径存储起来下次使用。如果需要下次在使用,可通过 FileSystemManager.saveFile() 或 FileSystemManager.copyFile() 接口把本地临时文件转换成本地缓存文件或本地用户文件。
示例
wx.chooseImage({
success: function (res) {
var tempFilePaths = res.tempFilePaths // tempFilePaths 的每一项是一个本地临时文件路径
}
})
本地缓存文件
本地缓存文件只能通过调用特定接口产生,不能直接写入内容。本地缓存文件产生后,重启之后仍可用。本地缓存文件只能通过 FileSystemManager.saveFile() 接口将本地临时文件保存获得。
示例
fs.saveFile({
tempFilePath: '', // 传入一个本地临时文件路径
success(res) {
console.log(res.savedFilePath) // res.savedFilePath 为一个本地缓存文件路径
}
})
注意:本地缓存文件是最初的设计,1.7.0
版本开始,提供了功能更完整的本地用户文件,可以完全覆盖本地缓存文件的功能,如果不需要兼容低于 1.7.0
版本,可以不使用本地缓存文件。
本地用户文件
本地用户文件是从 1.7.0
版本开始新增的概念。我们提供了一个用户文件目录给开发者,开发者对这个目录有完全自由的读写权限。通过 wx.env.USER_DATA_PATH
可以获取到这个目录的路径。
示例
// 在本地用户文件目录下创建一个文件 a.txt,写入内容 "hello, world"
const fs = wx.getFileSystemManager()
fs.writeFileSync(`${wx.env.USER_DATA_PATH}/hello.txt`, 'hello, world', 'utf8')
三、Cocos Creator 介绍
小游戏环境的资源管理
在小游戏环境中,资源管理是最特殊的部分,它和浏览器的不同在于下面四点:
- 小游戏的包内体积不能够超过 4mb,包含所有代码和资源,额外的资源必须通过网络请求下载。
- 对于从远程服务器下载的文件,小游戏环境没有浏览器的缓存以及过期更新机制。
- 对于小游戏包内资源,小游戏环境内并不是按需加载的,而是一次性加载所有包内资源,然后再启动页面。
- 不可以从远程服务器下载脚本文件。
这里引出了两个关键的问题,首页面加载速度和远程资源缓存及版本管理。对于首页面加载速度,我们建议用户只保存脚本文件在小游戏包内,其他资源都从远程服务器下载。而远程资源的下载、缓存和版本管理,其实在 Cocos Creator 中,已经帮用户做好了。下面我就来解释一下这部分的逻辑。
在小游戏环境中,我们提供了一个 wxDownloader 对象,给它设置了 REMOTE_SERVER_ROOT
属性后,引擎下载资源的逻辑就变成:
- 检查资源是否在小游戏包内
- 不存在则查询本地缓存资源
- 如果没有缓存就从远程服务器下载
- 下载后保存到小游戏应用缓存内供再次访问时使用
同时,当开启引擎的 md5Cache 功能后,文件的 url 会随着文件内容的改变而改变,这样当游戏发布新版本后,旧版本的资源在缓存中就自然失效了,只能从服务器请求新的资源,也就达到了版本控制的效果。
具体来说,开发者需要做的是:
- 构建时,勾选 md5Cache 功能。
- 将小游戏发布包中的 res 文件夹完整的上传到服务器。
- 删除发布包内的 res 文件夹。
- 在构建发布面板中设置
远程服务地址
。 - 对于测试阶段来说,可能你无法部署到正式服务器上,需要用本地服务器来测试,那么请在微信开发者工具中打开详情页面,勾选项目设置中的
不检验安全域名、TLS 版本以及 HTTPS 证书
选项。
四、实战
1、cocos creator 构建发布中设置【远程服务器地址】。并且选中MD5 Cache。
2、本地配置好的可访问路径。
3、将构建出来的res整体替换站点res。并且删掉构建出来的res。
五、总结
1、Error 4916, please go to https://github.com/cocos-creator/engine/blob/master/EngineErrorMap.md#491613 to see details. Arguments: 4aGsrZzohDNKpivyOlzMee;这错误一般是路径错误引起的,可以去微信开发者工具 libs/wx-downloader.js 中打印查看并解决。
2、不能热更新代码文件,修改JS必须重新提交审核,也许你会想直接把js放到resource目录下跟图片等资源一起更新,是不允许的,生成版本时js会自动的合并到项目的js文件中。
3、更多问题,欢迎加QQ群交流:418177552