-前言-
不知道你知不知道Laya有一個查找未被使用的資源功能,在UI編輯器狀態下按F4彈出,不過這個功能實在雞肋,只能查找在page中引用過的資源,但是我們正常開發下很多資源是在代碼中,或者配置到配置檔中的,所以需要根據自己的需求更改。如果放到Unity我估計就放棄了,直接寫腳本來跑刪除邏輯,不過既然Laya是開源引擎,引擎代碼又是基於nodejs環境寫的,那通過簡單修改就能實現我們想要的結果了。
-正文-
找到對應邏輯代碼
首先到你Laya的安裝目錄下找到resources->app->out->vs->layaEditor->layabuilder.max.js,關於IDE相關的代碼就在這裏。app目錄是自帶nodejs環境的,因此我們可以調用諸如fs這些文件操作API。控制查找未被使用資源的面板名稱爲FindUnUsedRes。我們所要實現的功能主要就着手修改這個類。
//當我們點擊查找按鈕之後的邏輯處理
__proto.onFindBtnClick=function(e){
this.resultBox.visible=true;
this._arr=ResManager.findUnUsed();
this.msgTxt.text=Sys.lang("共找到 {0} 個資源",this._arr.length);
this.checkSelectAll.selected=true;
this.onCheckSelectAllChange(null);
this.checkSelectAll.on("change",this,this.onCheckSelectAllChange);
}
找到這裏就好說了,我們修改find規則就能符合我們想要查找的資源類型。
修改UI界面
作爲一個合格的前端肯定要符合我們使用習慣,在不修改現有使用的情況下,我們添加兩個複選框,codeCheck及whiteListCheck,這兩個複選框選中後我們就去代碼中匹配資源以及在我們定義的白名單中匹配資源。LayaIDE用的UI庫與我們項目開發中使用的UI庫是一樣的,熟悉Laya的同學應該會熟悉這套UI框架。
//構造函數
function FindUnUsedRes(){
this._arr=null;
this.isCodeChange=false;
FindUnUsedRes.__super.call(this);
this.findBtn.on("click",this,this.onFindBtnClick);
this.list.mouseHandler=new Handler(this,this.onList);
this.delBtn.on("click",this,this.onDelBtnClick);
//以下爲我們自己添加的代碼
this.codeCheck = new CheckBox("comp/checkbox.png");
this.codeCheck.pos(this.findBtn.x + this.findBtn.width + 20,
this.findBtn.y + this.findBtn.height / 2 - this.codeCheck.height / 2);
this.addChild(this.codeCheck);
var tfCodeCheck = new Label("查找代碼");
tfCodeCheck.fontSize = 14;
tfCodeCheck.color = "#ffffff";
tfCodeCheck.pos(this.codeCheck.x + this.codeCheck.width + 5,this.codeCheck.y);
this.addChild(tfCodeCheck);
this.whiteListCheck = new CheckBox("comp/checkbox.png");
this.whiteListCheck.pos(this.codeCheck.x,this.codeCheck.y + this.codeCheck.height + 5);
this.addChild(this.whiteListCheck);
var tfWhite = new Label("檢測白名單");
tfWhite.fontSize = 14;
tfWhite.color = "#ffffff";
tfWhite.pos(this.whiteListCheck.x + this.whiteListCheck.width + 5,this.whiteListCheck.y);
this.addChild(tfWhite);
}
以上我們添加了兩個複選框以及複選框的說明文本,不過目前還沒有實現對應篩選邏輯,我們重啓或者刷新IDE按F4查看變化如下。
處理查詢邏輯
查詢邏輯通過ResManager->findUnUsed接口查詢未被使用的資源。之前是沒有參數的查詢,爲了實現我們的功能,我們把兩個複選框的狀態傳入這個接口,當複選框選上的時候就執行我們新寫上去的邏輯。
ResManager.findUnUsed=function(isCodeCheck,useWhiteList){
//以下爲新加代碼
(isCodeCheck===void 0) && (isCodeCheck= false);
(useWhiteList===void 0) && (useWhiteList = false);
//以上爲新加代碼
var reses;
reses=ResFileManager.getAllResLinkList();
var pages=FileManager.getFileList(FileManager.getWorkPath("laya/pages/"));
var i=0,len=0;
var a;
for(var $each_a in pages){
a=pages[$each_a];
var path=a;
if(FileTools.isDirectory(path))continue ;
var txt=FileManager.readTxtFile(path);
for (i=reses.length-1;i >-1;i--){
var item=reses[i];
if(item.indexOf("@")>=0||item.indexOf("$")>=0){
reses.splice(i,1);
continue ;
}
if (txt.indexOf("\""+item+"\"")!=-1){
reses.splice(i,1);
}
}
};
//以下爲新加代碼
if(useWhiteList){
//讀取項目根目錄下unusewhitelist.json配置
var white = FileManager.readJSONFile(FileManager.getWorkPath("") + "\\unusewhitelist.json");
if(white instanceof Array && white.length > 0){
for(i=reses.length - 1;i > -1;i--){
var item = reses[i];
if(item.indexOf("@")>=0||item.indexOf("$")>=0){
reses.splice(i,1);
continue ;
}
for(var j = 0;j < white.length;++j){
var wi = white[j];
if(item.indexOf(wi) != -1){
reses.splice(i,1);
break;
}
}
}
}
}
if(isCodeCheck){
//直接讀取bin目錄下經過編譯打包後的bundle.js文件
var codes = FileManager.getFileList(FileManager.getWorkPath("bin/js/"));
for(var jsI in codes){
var jsPath = codes[jsI];
if(FileTools.isDirectory(jsPath))continue ;
var txt = FileManager.readTxtFile(jsPath);
for(i=reses.length - 1;i > -1;i--){
var item = reses[i];
if(item.indexOf("@")>=0||item.indexOf("$")>=0){
reses.splice(i,1);
continue ;
}
if (txt.indexOf("\""+item+"\"")!=-1){
reses.splice(i,1);
}else{
var gR = item.split(new RegExp("\\d+"));
if(txt.indexOf("\""+gR[0]+"\"") != -1){
reses.splice(i,1);
}//TODO 增加匹配_
}
}
}
}
//以上爲新加代碼
var rst;
rst=[];
len=reses.length;
for(i=0;i<len;i++){
rst.push({label:reses[i],path:FileManager.getResPath(reses[i])});
}
return rst;
}
上面代碼中註釋之間的就是我們新加上的處理代碼,邏輯其實很簡單,就是字符串匹配。如果你有別的匹配需求還有可以寫別的,我這裏只是拋磚引玉,代碼本身的性能也沒去考慮過。主要是爲了實現功能。
第一個循環是Laya默認從page中查詢的邏輯,第二個是從我們定義的白名單中的查詢邏輯,第三個循環是從bundle.js中查詢的邏輯。
當我們沒有白名單的時候即使選上了查詢也不會進行查詢,因此我們需要配置一個白名單,名字與代碼中取的名字一樣就行,我這裏的名字叫做unusewhitelist.json,放到項目的根目錄。
這個白名單根據你自身的項目需求去配置文件名前綴後綴或者部分文件名都可以。
輸出查詢日誌
既然都修改了代碼了,我們就完成最後一步,將我們查詢日誌輸出到項目根目錄中,之前在Laya中我們查詢是沒辦法將查詢結果選中的,因此我們可以將其結果輸出到一個文件中,供我們參考。這一步就要回到我們的查詢結果之後去處理。修改onFindBtnClick函數。
__proto.onFindBtnClick=function(e){
this.resultBox.visible=true;
this._arr=ResManager.findUnUsed(this.depthCheck.selected,this.whiteListCheck.selected);
this.msgTxt.text=Sys.lang("共找到 {0} 個資源",this._arr.length);
this.checkSelectAll.selected=true;
this.onCheckSelectAllChange(null);
this.checkSelectAll.on("change",this,this.onCheckSelectAllChange);
//將結果輸出
FileManager.createJSONFile(FileManager.getWorkPath("") + "\\finunusedLog.json",this._arr);
}
這裏我們將查詢結果輸出到了項目根目錄下的finunuseLog.json文件中供我們參考查詢。至此我們所有功能已經實現。如果你覺得還不夠可以自行修改來滿足自己的功能。下面我們來比較下查詢結果與之前的不同。
由上面結果可見,我們代碼中還有很多動態引用圖片資源的代碼,這樣修改之後就敢放心大膽的刪除不需要的資源了。