1. ホーム
  2. Web プログラミング
  3. 関連情報

スクラッチ3.0二次開発におけるスクラッチブロックのコンパイルフリー改造問題

2022-01-17 07:51:27

scratch-blocks のコンパイル問題: scratch-gui が依存している scratch-blocks モジュールは、インストール時にコンパイル時にエラーを報告します。

理由 windowst システムでは、コード圧縮処理は build.py をクロージャープラグインで処理し、Google のサーバーに送信して圧縮し、その結果 blocks_compressed.js, blocks_compressed_horizontal.js, blocks_compressed_vertical.js が生成されるそうです。(linux システムでは、正常にコンパイルされるとの報告もあります。) build.py を実行すると、574 行目でウィンドウシステムが大量の情報の流れを処理する必要があるため、エラーが発生します。しかし、たとえ成功しても、その後、中国ではアクセスできないことが多いGoogleのサーバーにコードを送らなければならないため、コンパイルに失敗することが多いようです。 この方法は、変更するたびにコードを一度コンパイルする必要があるため、効率が悪く、時間もかかります。

スクラッチブロックのコードをコンパイルせずに修正し、即座に動作させる方法はないのでしょうか?答えは「イエス」です。

scratch 3.0ではどのようにscratch-blocksを導入しているのですか?スクラッチブロックはスクラッチガイのソースファイル srccontainersblocks.jsx で導入されています。

import VMScratchBlocks from '. /lib/blocks';

さて...これが修正されたブロックですが、呼び出しのパスをたどって、対応するロール(ターゲット)ブロックのメニュー項目を修正するためのファイルsrclibblocks.jsを開いてみます。

まず、スクラッチブロックを導入し、コンパイルされたファイルである

import ScratchBlocks from 'scratch-blocks';

次に、vmのデータを元に、ブロックのメニュー項目を修正します。例えば、looks_costumeブロックを修正するコードは、以下の通りです。

 ScratchBlocks.Blocks.looks_costume.init = function () {
        const json = jsonForMenuBlock('COSTUME', costumesMenu, looksColors, []);
        this.jsonInit(json);
    };

変更前、looks_costumeブロックのメニュー項目は以下のようなものでした。

メニュー項目は、スクラッチブロックで元々定義されていたもので、変更はありません。

修正箇所はこのようになります。

ほらね。メニューアイテムのデータはvmにリンクされています。

例えば、ワークスペースのインターフェースを変更して、ブロック上にポップアップメニューの項目を表示させ、「コメントを追加」を残して他の2つの項目を削除したい場合、変更前は右クリックのポップアップメニューは次のようになります。

srclibの下に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)); This is the commented out code
            if (this.isEditable() && this.workspace.options.comments) {
                menuOptions.push(Blockly.ContextMenu.blockCommentOption(block));
            }
            //menuOptions.push(Blockly.ContextMenu.blockDeleteOption(block)); this is the commented out code
        } 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を使ってコードを書けるようになりました。

そして、srclibblocks.js ファイルに導入します。

blockSvgModify はインポートされた関数変数です。

インターフェイスを最終的に更新し、変更を反映させます。

方法 変更するスクラッチブロックのコードを知っていて、そのコードをjsファイルにコピーして修正し、関数としてエクスポートし、引数にScratchBlockを渡すと、関数は変更後のスクラッチブロックファイルを返します。

まとめ:スクラッチブロックをファイルに導入し、そのファイルの中でスクラッチブロックの関数、プロパティ、メソッドを修正し、エクスポートすることで、欲しい効果を実現することができます。そして、この方法がホットモディファイです。reactを修正するように、修正するたびにそれに応じてguiのインターフェイスが変わるので、ソースファイルを何度もコンパイルするという面倒な作業を省くことができます。

スクラッチ3.0二次開発におけるスクラッチブロックのコンパイルフリー化についての記事は以上です。スクラッチブロックのコンパイルフリー化の内容については、スクリプトハウスの過去記事を検索いただくか、引き続き以下の関連記事を閲覧ください。今後ともスクリプトハウスをよろしくお願いします