解析scratch3.0二次開發之scratch-blocks免編譯修改問題
scratch-blocks編譯的時候會出現的問題:scratch-gui依賴的scratch-blocks模塊在安裝的時候編譯會報錯。
原因:scratch-blocks編譯時要調用的build.py文件運行時發生錯誤。windowst系統下,代碼壓縮的過程是build.py通過一個closure-library的插件處理後,發送到谷歌的服務器進行壓縮,返回的結果會生成blocks_compressed.js,blocks_compressed_horizontal.js,blocks_compressed_vertical.js這幾個文件。(linux系統下,有網友反映會編譯成功的。)build.py運行時,因為window系統在574行處要處理大量的信息流,所以導致錯誤發生。但即便成功,因為之後要把代碼發送到國內經常訪問不到的谷歌服務器,所以也會經常編譯失敗。這種方法每修改一次代碼就要編譯一次,效率比較低,比較耗時。
有沒有種方法不用編譯,就能修改scratch-blocks代碼,而且能即時生效呢?答案是,有的。
scratch3.0是怎麼引進scratch-blocks的呢?在scratch-gui的源文件src\containers\blocks.jsx中,引入瞭scratch-blocks,
import VMScratchBlocks from '../lib/blocks';
嗯…這是經過修改後的blocks,我們再順著調用的路徑,打開文件src\lib\blocks.js,這文件的作用是修改對應的角色(target)塊的菜單項。
第一步,引入scratch-blocks,這是已經編譯好的文件
import ScratchBlocks from 'scratch-blocks';
第二步,根據vm的數據修改blocks的菜單項。比如looks_costume塊的修改代碼如下:
ScratchBlocks.Blocks.looks_costume.init = function () { const json = jsonForMenuBlock('COSTUME', costumesMenu, looksColors, []); this.jsonInit(json); };
在修改之前,looks_costume塊的菜單項這樣子的:
菜單項是原來在scratch-blocks裡定義的,沒有變化。
修改後是這樣子的:
看到沒?菜單項的數據和vm聯系起來瞭。
再舉個例子吧,比如修改workspace界面在block上右鍵彈出菜單項,我要保留’添加註釋’,然後把其他兩項去掉,修改前,右鍵彈出菜單是這樣子的:
在src\lib下創建scratch-blocks-modify文件夾,文件夾裡創建瞭blocks_svg.js文件,從scratch-blocks的core文件夾中找到blocks_svg.js,把其中需要修改的函數代碼復制過來。
修改的blocks_svg.js文件代碼如下 :
export default function(Blockly){ Blockly.BlockSvg.prototype.showContextMenu_ = function(e) { if (this.workspace.options.readOnly || !this.contextMenu) { return; } // Save the current block in a variable for use in closures. var block = this; var menuOptions = []; if (this.isDeletable() && this.isMovable() && !block.isInFlyout) { //menuOptions.push( // Blockly.ContextMenu.blockDuplicateOption(block, e)); 這是註釋掉的代碼 if (this.isEditable() && this.workspace.options.comments) { menuOptions.push(Blockly.ContextMenu.blockCommentOption(block)); } //menuOptions.push(Blockly.ContextMenu.blockDeleteOption(block));這是註釋掉的代碼 } else if (this.parentBlock_ && this.isShadow_) { this.parentBlock_.showContextMenu_(e); return; } // Allow the block to add or modify menuOptions. if (this.customContextMenu) { this.customContextMenu(menuOptions); } Blockly.ContextMenu.show(e, menuOptions, this.RTL); Blockly.ContextMenu.currentBlock = this; }; }
註意:現在可以使用es6來編寫代碼瞭。
然後在src\lib\blocks.js文件引入 :
blockSvgModify是導入的函數變量。
最後刷新下界面,修改生效:
方法:知道要修改的scratch-blocks的代碼,然後把代碼復制到一個js文件中修改,作為一個函數導出來,再把ScratchBlock作為參數傳進去,函數返回的就是改過後的scratch-block文件瞭。
小結:我們可以通過引入scratch-block到一個文件中,在這個文件中修改我們想要修改的scratch-block函數、屬性和方法,再導出來,實現我們想要的效果。而且這種方法是熱修改。和修改react一樣,每次修改會引起gui界面相應的變化,避免反復編譯源文件繁瑣的過程。
到此這篇關於scratch3.0二次開發之scratch-blocks的免編譯修改方法的文章就介紹到這瞭,更多相關scratch blocks的免編譯內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Scratch3.0二次開發之windows環境下打包成exe的流程
- 淺談IDEA Scratch files萬能的臨時文件功能
- Scratch3.0 頁面初始化同時加載sb3文件的操作代碼
- django連接Mysql中已有數據庫的方法詳解
- Scratch3.0初始化加載七牛雲上的sbs文件的方法