在白鷺引擎發佈了5.2.7版本中新增長了命令行,增長自動合圖插件TextureMergerPlugin功能。今天,咱們以一個EUI案例來展現自動合圖插件的具體使用方法和注意事項。javascript
此外,咱們在本文還融入了UglifyPlugin、ResSplitPlugin、ZipPlugin等插件使用方法。開發者利用上述4款插件,將實現代碼包體積更小、更好管理的目標。html
目錄:java
項目初始化
1. 把index.html中的`data-scale-mode`改爲`fixedWidth`
2. 打開EgretLauncher,將本項目發佈成微信小遊戲
3. 打開微信開發者工具
使用UglifyPlugin壓縮代碼
在微信開發者工具能夠看到,js文件夾中5個庫文件和一個`main.js`。
如今需求是是要把庫文件壓縮到一個文件`lib.min.js`中。
回到EgretWing,編輯sctipts下的config.wxgame.ts:
node
//***其餘代碼*** // if (command == 'build') { return { outputDir, commands: [ // 清理js,resource文件夾 new CleanPlugin({ matchers: ["js", "resource"] }), new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }), new ExmlPlugin('commonjs'), // 非 EUI 項目關閉此設置 new WxgamePlugin(), // 壓縮插件 new UglifyPlugin([ { // 須要被壓縮的文件 sources: [ "libs/modules/egret/egret.js", "libs/modules/eui/eui.js", "libs/modules/assetsmanager/assetsmanager.js", "libs/modules/tween/tween.js", ], // 壓縮後的文件 target: "lib.min.js" } ]), new ManifestPlugin({ output: 'manifest.js' }) ] } } // // ***其餘代碼***
保存後在終端執行:linux
egret build
能夠在微信開發者工具看到發佈後的代碼,js文件夾內的庫文件已經被壓縮到lib.min.js。
可是報錯,找不到eui,這是由於自動生成的`manifest.js`裏面對js的引用順序出錯,須要優先引用lib.min.js
打開根目錄下的`manifest.js`, 修改一下引用順序。
c++
require("js/lib.min.js") require("js/main.js") require("js/default.thm.js")
每次編譯的時候`manifest.js`都會被從新生成,因此咱們使用一個自定義腳原本修改他們的順序
打開 scripts下的myPlugin.ts :
git
/** * 示例自定義插件,您能夠查閱 http://developer.egret.com/cn/2d/projectConfig/cmdExtensionPluginin/ * 瞭解如何開發一個自定義插件 */ export class CustomPlugin implements plugins.Command { private buffer constructor() { } async onFile(file: plugins.File) { // 保存manifest.js文件的內容 if(file.basename.indexOf('manifest.js') > -1) { this.buffer = file.contents } return file; } async onFinish(commandContext: plugins.CommandContext) { // 把'lib.min.js'移到第一位 if (this.buffer) { let contents: string = this.buffer.toString() let arr = contents.split('\n') let lib = null arr.forEach((item, index) => { if (item.indexOf('lib.min.js') > -1) { lib = item arr.splice(index, 1) } }) if (lib != null) { arr.unshift(lib) } let newCont = arr.join('\n') commandContext.createFile('manifest.js', new Buffer(newCont)) } } }
這個文件就是用來自定義插件的,在config.wxgame.ts中已經默認引用,因此只須要調用便可,注意調用順序
github
new ManifestPlugin({ output: 'manifest.js' }), // 在manifest.js生成以後調用 new CustomPlugin()
使用ResSplitPlugin分離資源文件
由於微信對代碼包的大小是有限制的,總大小不能超過4M(使用分包功能能夠提高到8M),因此咱們須要經過ResSplitPlugin把某些遊戲資源文件分離出去,將遊戲資源放置在一個外部CDN服務器上,須要的時候動態加載便可。
編輯config.wxgame.ts:
npm
// ***其餘代碼*** // new ResSplitPlugin({ verbose: false, matchers: [ // from 使用glob表達式來匹配文件, projectName就是項目的名字 { from: "resource/art/about/**.**", to: `${projectName}_wxgame_remote` }, { from: "resource/art/heros_goods/**.**", to: `${projectName}_wxgame_remote` } ] }) // ***其餘代碼***
保存後在終端執行:json
egret build
微信開發者工具中resource > art 下的`about`和`heros_goods`已經不在了。
被分離出去的在項目根目錄中 `egret-eui-demo_wxgame_remote` 文件夾內。
使用ZipPlugin把文件壓縮成zip格式
爲了減小加載次數和傳輸量,咱們能夠把文件壓縮成zip格式,使用的時候可使用第三方庫JSZip來讀取使用zip文件。
使用ZipPlugin插件以前,須要安裝cross-zip 和 cross-zip-cli , 在終端中輸入:
//全局安裝 npm install cross-zip -g npm install cross-zip-cli -g
安裝完成以後,在config.wxgame.ts添加代碼:
new ZipPlugin({ mergeSelector: p => { // 若是文件是assets/路徑下的, 壓縮到assets.zip if (p.indexOf("assets/") >= 0) { return "assets.zip" } } })
項目中其實assets裏面的資源都是沒有用到的,這裏咱們用它來演示壓縮插件的使用。
保存後在終端執行:
egret build
執行以後能夠在微信開發者工具看到,resource目錄下原來的assets文件夾已經被壓縮成了assets.zip。
使用TextureMergerPlugin,ConvertResConfigFilePlugin合併紋理集
項目中使用的圖片資源都是單獨的png文件,在加載的時候每張圖片都會單獨請求。咱們能夠經過合併紋理集的方式把這些圖片合成一張圖,以減小請求數量。
使用插件以前,咱們須要有紋理集的配置文件`tmpropject`, 能夠用兩種方式生成:
1. 使用[TextureMerger工具](http://developer.egret.com/cn/github/egret-docs/tools/TextureMerger/manual/index.html)
2. 執行腳本生成
這裏使用第二種方法,使用腳本autoMerger.js:
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var fs = require("fs"); var path = require("path"); var resjsons = ["resource/default.res.json"]; //要掃描的res.json文件 var targetDir = "resource/TextureMerger"; //輸出目錄 var pathNor = path.relative(targetDir, "resource"); //返回一個相對路徑 var tempindex = 0; //建立輸出文件夾 if (resjsons.length > 0) { if (!fs.existsSync(targetDir)) { // var paths = path.normalize(targetDir).split("\\"); //windows 下使用 var paths = path.normalize(targetDir).split("\/"); //mac linux 下使用 var target = "."; for (var _i = 0, paths_1 = paths; _i < paths_1.length; _i++) { var p = paths_1[_i]; // target += ("\\" + p); // windows 下使用 target += ("\/" + p); // mac linux 下使用 if (!fs.existsSync(target)) // 根據路徑建立文件夾 fs.mkdirSync(target); } } } var _loop_1 = function (resJson) { // 判斷是不是res.json文件 if (fs.existsSync(resJson) && resJson.indexOf("res.json") > -1) { var defaultJson = fs.readFileSync(resJson, "utf-8"); // 解析res.json文件內容 var defaultObject = JSON.parse(defaultJson); var groups = defaultObject.groups; //組 var resources = defaultObject.resources; //資源 var resourcesHash_1 = {}; // 用來存放resources的資源信息 // 遍歷resources for (var _i = 0, resources_1 = resources; _i < resources_1.length; _i++) { var resource = resources_1[_i]; resourcesHash_1[resource.name] = resource.url; } // 遍歷groups for (var _a = 0, groups_1 = groups; _a < groups_1.length; _a++) { var group = groups_1[_a]; var tmproject = {}; //用來存放tmproject文件的信息 // tmproject文件配置 tmproject["options"] = { "layoutMath": "2", "sizeMode": "2n", "useExtension": 1, "layoutGap": 1, "extend": 0 }; // projectName tmproject["projectName"] = group.name + "_" + tempindex; // 版本 tmproject["version"] = 5; tempindex++; // 獲取res.json分組的keys, 並分割成數組 var oldkeys = group.keys.split(","); var oldkeysHash = {}; // 遍歷oldkeys for (var _b = 0, oldkeys_1 = oldkeys; _b < oldkeys_1.length; _b++) { var key = oldkeys_1[_b]; // 保存到oldkeysHash對象中 oldkeysHash[key] = true; } var newKeys = []; // 遍歷oldkeys for (var _c = 0, oldkeys_2 = oldkeys; _c < oldkeys_2.length; _c++) { var key = oldkeys_2[_c]; if (key.indexOf("json") == -1) { if (!oldkeysHash[key.replace("png", "json")]) { //粒子和龍骨對應的圖集不合圖 if (!oldkeysHash[key.replace("png", "fnt")]) //位圖字體 newKeys.push(key); } else if (key.indexOf("jpg") > -1) { newKeys.push(key); } } } oldkeysHash = {}; oldkeys = []; // files路徑 var urls = newKeys.map(function (key) { return path.join(pathNor, resourcesHash_1[key]); }); tmproject["files"] = urls; // 根據tmproject寫入文件 if (urls.length > 0) { fs.writeFileSync(path.join(targetDir, tmproject["projectName"] + ".tmproject"), JSON.stringify(tmproject)); } tmproject = {}; } } }; //根據數組開始掃描 for (var _a = 0, resjsons_1 = resjsons; _a < resjsons_1.length; _a++) { var resJson = resjsons_1[_a]; _loop_1(resJson); }
把這個腳本放在scripts文件夾內,這個腳本是根據項目的`default.res.json`文件的內容來生成`tmpropject`文件
在終端中執行:
node scripts/autoMerger.js
執行成功以後能夠在resource文件夾中看到多出了一個TextureMerger文件夾,裏面就是根據`default.res.json`分組生成的`tmpropject`文件。
如今只須要執行TextureMergerPlugin插件就能夠自動合併,這裏須要注意TextureMergerPlugin依賴 TextureMerger 1.7 以上的版本,若是不符合請自行安裝,而且在運行時TextureMerger須要處於關閉狀態。
new TextureMergerPlugin({textureMergerRoot:[ 'resource']})
保存後在終端執行:
egret build
執行完成後,在微信開發者工具能夠看到,resource > TextureMerger 內新增了三個png文件,就是合併以後的紋理集。遊戲運行的時候只須要加載這三個紋理集就能夠,無需加載那些單獨的png文件可是須要去res.json裏面配置,把單獨的資源引用都刪除,加上紋理集的引用。
這些操做固然不須要手動去完成,如今只須要使用ConvertResConfigFilePlugin插件就能夠實現這個功能。
編輯config.wxgame.ts:
new TextureMergerPlugin(), new ConvertResConfigFilePlugin({ resourceConfigFiles: [{ filename: "resource/default.res.json", root: "resource/" }], nameSelector: (p) => { return path.basename(p).split(".").join("_") }, TM_Verbose: true })
保存後在終端執行:
egret build
在微信開發者工具中,打開調試器,在network面板能夠看到加載的紋理集。
這裏有個注意事項,在遊戲中點擊英雄按鈕,切換到英雄場景時,會發現列表裏面的圖片加載不出來。
在network面板能夠看到加載請求是單獨的png文件,而不是紋理集。
這是由於列表中的圖片地址是直接使用url。
// 原始數組 let dataArr:any[] = [ {image: 'resource/art/heros_goods/heros01.png', name: '亞特伍德', value: '評價: 很特麼厲害, 隨心所欲', isSelected: false}, {image: 'resource/art/heros_goods/heros02.png', name: '亞特伍德', value: '評價: 很特麼厲害, 隨心所欲', isSelected: false}, {image: 'resource/art/heros_goods/heros03.png', name: '亞特伍德', value: '評價: 很特麼厲害, 隨心所欲', isSelected: true}, {image: 'resource/art/heros_goods/heros04.png', name: '亞特伍德', value: '評價: 很特麼厲害, 隨心所欲', isSelected: false}, {image: 'resource/art/heros_goods/heros05.png', name: '亞特伍德', value: '評價: 很特麼厲害, 隨心所欲', isSelected: false}, {image: 'resource/art/heros_goods/heros06.png', name: '亞特伍德', value: '評價: 很特麼厲害, 隨心所欲', isSelected: false}, {image: 'resource/art/heros_goods/heros07.png', name: '亞特伍德', value: '評價: 很特麼厲害, 隨心所欲', isSelected: false} ] // 轉成eui數據 let euiArr:eui.ArrayCollection = new eui.ArrayCollection(dataArr) // 把list_hero數據源設置成euiArr this.list_hero.dataProvider = euiArr // 設置list_hero的項呈視器 (這裏直接寫類名,而不是寫實例) this.list_hero.itemRenderer = heroList_item
這種引用方式的圖片,須要開發者手動在代碼中修改,將圖片地址修改爲紋理集中的圖片。
結語 本文經過使用UglifyPlugin,ResSplitPlugin,ZipPlugin,TextureMergerPlugin,ConvertResConfigFilePlugin插件,使項目發佈到微信小程序以後的代碼包體積減少,用戶發起的請求數變少,且將代碼混淆壓縮。 使用Egret自帶的插件,已經能夠知足開發者的基本需求,若是有針對項目的特殊需求,能夠選擇[自定義插件](http://developer.egret.com/cn/github/egret-docs/Engine2D/projectConfig/cmdExtensionPlugin/index.html)。