BlocklyでWebSocket通信　[その１：カスタムブロックの作り方]

# この記事は・・・

- Google謹製のBlocklyのお話。
- Blocklyはブロックプログラミングのためのフレームワークで拡張可能。
    - そもそもScratch3.0がBlcoklyベース
- BlocklyでWebSocketなんか使えたら夢が広がるよね。
    - 小学生が、ネコ動かすだけじゃなく、通信プログラム書いたりできるよね。
- Blocklyの拡張を勉強するために習作としてWebSocketブロックを作ろう！
- ついでに、Blocklyを拡張したい人向けにHow-toを残しておこう・・・・


***と、そんな意気込みで書き始めたら記事が長くなってしまいました。***
***そこで記事を２回に分ける事にしました・・・・***

- ***その１：カスタムブロックの作り方***（この記事）
- ***その２：WebSocket通信の実現*** (未完成)


# Blocklyとは

- https://developers.google.com/blockly/

BlocklyはGoogleが開発している、拡張可能なブロックプログラミングフレームワークです。基本的な命令はあるので、[Play Ground](https://blockly-demo.appspot.com/static/tests/playground.html)でプログラミングして遊ぶ事も出来ますが、特定の環境・言語に依存した機能は一切持っていないため、これ単体では***意味のある事***は出来ません。つまり、Scratchのようにネコを動かす事は出来ないんです。

では、何のためのツールか？というと、Scratchのような独自のブロックプログラミング環境を構築したい人のうち、「でも、ブロックのデザインや操作のロジックを組み立てるのはメンドクサイから、何かツールでちゃちやっと出来ないかな？」という人向けの便利ツールです。事実Scrath3.0はBlocklyベースだそうですね。

世の小学生はScratchを直接使うでしょうし、独自のブロックプログラミング環境を子供にプレゼントするお父さんなんてそうそう居ないでしょうから、Blocklyを直接使うニーズなんて、あまり無いのかもしれませんが、BlocklyはJavaScriptで簡単に拡張可能である事を謳っていますので、習作として何か作って見たくなりますよね。

習作なんで、拡張の方法が理解できれば何でも良いのですが、ネコを走らす機能を作っても二番煎じですので、何かすこし***意味のある機能***を作りましょう。という事でWebSocketです。

以前、サイドワークで小学生向けのScratch講座を手伝ったのですが、そこで感じたのは、結局、プログラミングというよりは、ちょっとインタラクティブな紙芝居になってしまうケースがあまりにも多いなという事でした。小学校でプログラミングの授業か始まりますが、複数の生徒たちが一斉にプログラミングをするのですから、通信機能ぐらいあったって良いと思う訳です。Nintendo Switchだってネットワーク対戦できる訳で、彼らが最初に触るプログラミング環境に、友達のプログラムと簡単に通信できる機能があったとしても、決して「理解できない機能」という事はないはずです。

Blocklyはブラウザ上でプログラミングと実行が出来るツールです。ブラウザ上で通信と言えば、WebSocketですよね。ところがこのWebSocket、いや、WebSocketに限らず、最近のJavaScript系のツールは、***非同期実行***と***コールバック関数***の嵐です。

何が問題かといえば、ブロックプログラミングの殆どが、非同期で起こるイベント処理に、文法レベル(いやブロックレベルと言うべきか？)で対応していないのです。

例えばWebSocketはインスタンスを作った後に、各種ハンドラに関数を登録しておきます。

```JavaScript
//インスタンスの作成
const ws= new WebSocket('ws://foo')

//メッセージ受信の際に実行される関数を上書きして独自コードを入れ込む
ws.onmessage = (event)=>{
    console.log(event.data)
}
```

最近のJavaScriptの書き方は殆どがこんな感じで、コールバックが多階層入れ子になる事が問題にもなり、コールバック地獄などと呼ばれていますが、node-asyncやPromise等が出てきて、入れ子のコールバックをシンプルに表現できるようになりました。

ところが、ブロックプログラミングでは、そもそもコールバック関数を登録して・・・というような事がブロックレベルで対応していません。(Scratchの場合は、「〇〇が押されたら」というUIイベントに対する処理は書けますけど・・・)

という訳で、ちょっとその辺の工夫が、Blocklyの習作としては丁度良いかなと考えました。

# 完成品

完成した作品はGitHubとnpm上に置いてあります。WebSocketによるエコーサーバーと、今回作ったWebSocketブロックが使えるブロックプログラミング環境が含まれています。

- https://github.com/abarth500/Blockly-with-WebSocket
- https://www.npmjs.com/package/blockly-with-websocket

試しに実行したければ、以下のコマンドで一発でWebSocketエコーサーバーが起動します。(node.js環境が必要です)

```bash
npx blockly-with-websocket ja
```

起動したらブラウザを立ち上げて http://localhost:8080/ へ繋ぐと、Blocklyのプログラミング画面が表示されます。ここでWebSocketでエコーのクライアントを実装して、実行する事が出来ます。（サンプルコードはGitHubに画像で貼り付けてあります。）

なお、記事が長くなりWebSocketの話は、次回にしましたので、上記コードはこの記事では使いません。この記事では、一般論としてのカスタムブロックの作り方を説明しています。この記事で説明しているコードは上記とは別のGitHubリポジトリに置いています。ただし、公開しているコードは、このページの遥か下まで読み進めてできあがる上がる完成品で、記事自体は、どうやってそれを作るかをチュートリアル形式で段階を追って説明していますので、まずは記事を読み進めてください。

- このチュートリアルで作るコード
    - https://github.com/abarth500/blockly-custom-blocks-example

# カスタムブロックの作成

では、まずWebSocketのブロックを作るという前に、一般論としてどのようにカスタムブロック(ユーザが独自に定義したブロック)を作るのかを説明します。

## Blockly Developer Tools

Blocklyではブロックの定義や機能の実装などは、XMLやJSON、JavaScritpでできますので、基本的にはリファレンスを読んで、メモ帳か何かで実装していけばよいのですが、Blocklyでは簡単にブロックの定義を行うためのツール***Blockly Developer Tools***を用意しています。

- https://blockly-demo.appspot.com/static/demos/blockfactory/index.html

このツールを使うとBlocklyのカスタムブロックの作成がBlocklyでできます。なので、このツール自体、Blocklyの配布物の[demoフォルダ](https://github.com/google/blockly/tree/master/demos/blockfactory)にも入っています。

![Blockly Developer Toolsの初期画面](https://qiita-image-store.s3.amazonaws.com/0/348073/7efb76be-4b45-84c3-5967-82e8a6b64375.png)

画面は大きく四つの部分に分かれています。左側が***ブロック定義を実装***する画面、右側が上から順に、作ったブロックの***プレビュー (Preview)***と、***ブロック定義 (Block Definition)***、***動作の定義 (Generator stub)***です。

***ブロック定義***はJSONかJavaScriptから選べます。また***動作の定義***はJavaScript以外にも各種言語が選べます。ブラウザ上で動作させるならJavaScript一択だと思いますが、Blockly自体は、言語非依存で、ブロックで作られたプログラムを様々な言語にエクスポートする事ができるように設計されています。そうそう、言語非依存と言えば、Blocklyはプログラミング言語だけでなく、自然言語にも非依存であり、様々な言語に対応しています。***プレビュー (Preview)***の所にある**LTR**を**RTL**にすれば、アラビア語のような、右から左に書く言語でのプレビューもできます。

## ブロックの定義

初期画面ではブロックの定義として

- name
- inputs
- input形式
- 他ブロックとの接続形式
- tooltips
- help url
- colour

の項目があります。それらを定義する事でカスタムブロックを作っていきます。

### name

これはブロックの識別に使われるIDで、他と被らない名前を付けましょう。後で、ブロックが増えた時に、そのブロックが何なのかが分かる名前にするとよいでしょう。

### inputsとfield

このブロックに対する入力を定義します。「入力 - input」とありますが、ブロックの***見てくれ***全般の定義をここで行います。***input***に入れ込むブロックは左側ツールバーの***input***にまとまっています。
![ツールバー - input](https://qiita-image-store.s3.amazonaws.com/0/348073/06eeec89-fb94-5f21-1fea-4a975f358154.png)

ブロックは三種類、値とる***value input***、構文をとる***statement input***、何の機能もなさそうな***dummy input***です。この***input***には***fields***を入れ子にする事が出来ます。

では、***field***も見てみましょう。
![ツールバー - field](https://qiita-image-store.s3.amazonaws.com/0/348073/3034115d-0d26-2753-4c7c-062f68187e42.png)

HTMLを書いたことのある方でしたら、***input***というと、```<form>```を連想すると思いますが、それと似ています。

では、実際に組み合わせてみましょう。三種類の***input***に適当な***field***をくっつけた例を以下に示します。
![inputの例](https://qiita-image-store.s3.amazonaws.com/0/348073/9b4ad9f5-d1fc-6f29-54a3-5f3422ec4eca.png)

この定義で作られたブロックを次に示します。
![ブロックのプレビュー](https://qiita-image-store.s3.amazonaws.com/0/348073/e8f64387-91ac-0c7b-30e8-aeb3dccd7815.png)

このように***value input***、***statement input***、***dummy input***はそれぞれ、異なるブロックの外形になります。前者の二つは他のブロックを繋げる事が出来ます。

では***inputs***の下にある***[automatic] inputs***を変えると何が起こるのでしょうか。このセレクトは三つの値を取る事が出来ます。

- automatic
- external
- inline

これを***inline***に変えると、ブロックのプレビューは以下のように変化します。
![ブロックのプレビュー(internal)](https://qiita-image-store.s3.amazonaws.com/0/348073/e164f8ae-7db7-8900-c32b-091f8965a0ac.png)

この例だと、些細な違いしかありませんが、***value input***が複数ある場合、***external***だと接続点は縦に並びますが、***inline***だと横に並びます。機能の違いはありませんが、前後の文字との座りの良さで決めると良いでしょう。

### connection

すでに、Blocklyのブロックには二つの形がある事に気づいていると思います。１つは、上と下に凸凹があるタイプ、もう一つは左側にジグソーパズルのような突起があるタイプです。
![値ブロック](https://qiita-image-store.s3.amazonaws.com/0/348073/6553283d-e2ed-faa8-4858-8f0793ba1277.png)
![構文ブロック](https://qiita-image-store.s3.amazonaws.com/0/348073/e97b0cf4-e262-65dd-0565-e0256ee518e1.png)

前者が***構文ブロック***で、なんらかの処理を行うブロックになります。後者は***値ブロック***で、なんらかの値を返すブロックです。ここで、何らかの値や何らかの処理は、みなさんがJavaScriptで定義する訳で、***値ブロック***の中で何らかの処理を行ったりといった事は自由自在です。その前提の元、***構文ブロック***はプロシージャそのもので、***値ブロック***は式の右辺にくる値だと理解しておくと良いでしょう。

さて、今作ったブロックのプレビューを見てみると、この二つのどちらでも無い事に気づきます。突起が上下にも左にもありません。このままでは、他のブロックにくっつける事ができません。

このブロックを***構文ブロック***(突起が上下)にするのか、***値ブロック***(突起が左)にするのかは、[no connection]というセレクトで指定できます。ブロックの性質に応じて指定しましょう。

- ← left output (値ブロック)
![left output](https://qiita-image-store.s3.amazonaws.com/0/348073/52d1c0a6-0466-c26d-5092-b3aef165fed5.png)

- ↕ top+bottom connection (構文ブロック)
![top+bottom connection](https://qiita-image-store.s3.amazonaws.com/0/348073/14db6486-7b23-e57b-c986-6d7cf2c6d977.png)

- ↑ top connection (構文ブロック)
![top connection](https://qiita-image-store.s3.amazonaws.com/0/348073/0a87b88a-0e9f-34ef-db4e-c3ee1f7bd857.png)

- ↓ bottom connection (構文ブロック)
![bottom connection](https://qiita-image-store.s3.amazonaws.com/0/348073/3b9d5d9d-279d-a75f-54ed-fbb88d82f210.png)

### type

すでに気づいたかもしれませんが、接続タイプを***← left output***を指定した時に、ブロック定義に***output type***という項目が現れます。

![output typeという接続点が出てきた](https://qiita-image-store.s3.amazonaws.com/0/348073/749d06b8-da8c-120d-827a-f93a0cd6d5e9.png)

この***type***に接続できるブロックはツールバーの***type***のカテゴリにあります。

![ツールバー - type](https://qiita-image-store.s3.amazonaws.com/0/348073/ec60602b-a548-f421-25f4-82307a0c1eff.png)

これを***output type***に接続する事で、このブロックがどのような型のデータを吐き出すのかを定義できます。デフォルトは***any***で、型付けはされていません。***String***にすれば、この***値ブロック***は文字列を返すという事を宣言でききます。

これが何の役に立つのでしょうか？それを考えるには、***input***の方にも***type***があった事を思い出してください。

例えば***value input***の***type***に***string***を設定したとします。この場合、その接続点にくっつけられるブロックは***output type***に***string***をとる***値ブロック***のみに制限されます。Blocklyが翻訳され実行される言語(JavaScript等)は、基本的には型付けが弱い言語ですが、Blocklyはブロックを接続する制約として、最低限の型チェックの機能を持っている訳です。

### Colour

なぜ英国英語の綴りなのかは分かりませんが***ブロックの色***の事です。

![ツールバー - colour](https://qiita-image-store.s3.amazonaws.com/0/348073/d54bdb7c-2ee6-fac3-d9ae-f4412cd713b8.png)

色はHSV系で色相だけコントロールできるようになっています。元々用意されているブロックは以下の様にカテゴリが分けられており、それぞれシンボルカラーを持っています。自分で作るブロックが、それらどれかのカテゴリに入るなら、同じ色にすると良いでしょうし、それとは別に、独自のカテゴリとしてまとめ長ければ、デフォルトで使われていない色にすると良いでしょう。

![デフォルトのブロックカテゴリと色](https://qiita-image-store.s3.amazonaws.com/0/348073/a42e4e3a-f9b9-1164-b7c2-edfe733de4ab.png)

## ブロック定義

ビジュアルプログラミングの最大の懸念点は、プログラムが絵だけど、どーやって保存するの？って所だと思います。Blocklyではブロック定義は、JSON形式、あるいはJavaScript形式でエクスポートする事が出来ます。例えば、上記のブロックの定義は以下のようなJSON形式で表されます。

```json
{
  "type": "my_block",
  "message0": "値ブロックを連結できます %1 構文を入れ子にできます %2 定数入力に使います %3 %4 %5",
  "args0": [
    {
      "type": "input_value",
      "name": "value_block"
    },
    {
      "type": "input_statement",
      "name": "statement_blocks"
    },
    {
      "type": "field_checkbox",
      "name": "input_check",
      "checked": true
    },
    {
      "type": "field_input",
      "name": "input_text",
      "text": "default"
    },
    {
      "type": "field_number",
      "name": "input_num",
      "value": 0,
      "min": 0,
      "max": 5
    }
  ],
  "output": null,
  "colour": 210,
  "tooltip": "",
  "helpUrl": ""
}
```

このJSONファイルを保存しておけば、別のマシンや環境から呼び出して使う事が出来ます。BlocklyではこのJSON形式の他、JavaScript形式でもエクスポートする事が出来ます。どっちが良いかは分かりませんが、ファイルとして保存して置く場合や、使うときに一部を書き換えたりしたい場合はJSONの方が使い勝手が良いでしょうし、単にプログラム上に展開したいだけならJavaScirpt形式の方が```<srcipt>```で読み込むだけですので、手間が省けます。

## 動作の定義

ブロックは前節で説明した***みてくれの定義***の他にもうひとつ、***動作の定義***があります。前者はプログラミング言語非依存の部分で、後者が依存する部分です。定義が二ヵ所に分かれてちょっとややこしいのですが、この仕組みによって、言語に依存する部分をなるべく小さくするようにしています。

この部分は、エクスポートする言語毎につくる必要があります。もし作りたいシステムがJavaScriptだけで良いやという事でしたらJavaScriptのコードだけかけば良いですし、Pythonもという事なら、Pythonのコードも書かなければなりません。

- JavaScript定義の書き出し

```JavaScript
Blockly.JavaScript['my_block'] = function(block) {
  var value_value_block = Blockly.JavaScript.valueToCode(block, 'value_block', Blockly.JavaScript.ORDER_ATOMIC);
  var statements_statement_blocks = Blockly.JavaScript.statementToCode(block, 'statement_blocks');
  var checkbox_input_check = block.getFieldValue('input_check') == 'TRUE';
  var text_input_text = block.getFieldValue('input_text');
  var number_input_num = block.getFieldValue('input_num');
```
- Python定義の書き出し

```JavaScript
Blockly.Python['my_block'] = function(block) {
  var value_value_block = Blockly.Python.valueToCode(block, 'value_block', Blockly.Python.ORDER_ATOMIC);
  var statements_statement_blocks = Blockly.Python.statementToCode(block, 'statement_blocks');
  var checkbox_input_check = block.getFieldValue('input_check') == 'TRUE';
  var text_input_text = block.getFieldValue('input_text');
  var number_input_num = block.getFieldValue('input_num');
```

あれ？

両方JavaScriptじゃんと思われるかもしれませんが、その両方JavaScriptで正しいです。BlocklyはHTML+JavaScriptで全て動作します。あくまでこれはエクスポートする部分であり、エクスポートされるコードはPythonですが、エクスポート機能のコードはJavaScriptで実装されています。当然といえば当然ですね。

では、それに続く行を見てみましょう。

```JavaScript
  // TODO: Assemble Python into code variable.
  var code = '...';
```

この***...***の部分に、JavaScriptならJavaScriptのコード、PythonならPythonのコードを***文字列として***書いていくのです。

そう、Blocklyの本質は、文字列で書かれたプログラムを切った貼ったする事なんです。

では、二つの数を取り平均を返すブロックを考えてみましょう。定義は以下のようになります。



# 練習：平均値出力カスタムブロックを作る

では、実際に [Blockly Developer Tools](https://blockly-demo.appspot.com/static/demos/blockfactory/index.html) を使ってカスタムブロックを作ってみましょう。画面は３つのタブ、***Block Factory***、***Block Exporter***、***Workspace Factory***に分かれています。それぞれの機能を簡単に理解しておきましょう。

|      |   タブ   |  説明  |
| ---: | :---: | --- |
| 1 | Block Factory| カスタムブロックの定義  |
| 2 | Block Exporter| カスタムブロック定義のダウンロード  |
| 3 | Workspace Factory| プログラミング画面の設定と定義のダウンロード |

では、***Block Factory***タブで以下の仕様のブロックを定義してみましょう

- ２つの数値を入力にとり平均値を算出し、それを標準出力に出す

このプログラムを実現するために、２つのカスタムブロックを作りましょう

1. ２つの数値の平均値を返す***値ブロック***
2. 与えられた値を標準出力に出力する***構文ブロック***

## 値ブロックの定義

では、まず平均値を算出するブロックを作りましょう。ブロックにどんな説明を載せるかは、個人のセンス次第ですが、以下のように作ってしまうと、あまりよろしくないかもしれません。

![平均ブロック（いまいち）](https://qiita-image-store.s3.amazonaws.com/0/348073/dcbd626b-a290-bb18-b395-ec93835add50.png)

普段、普通のプログラミング言語やエクセル関数等を触っている人であれば、簡潔で分かりやすいのですが、ブロックプログラミング的か？と言われると、違うような気がします。では次のはどうでしょうか？

![平均ブロック](https://qiita-image-store.s3.amazonaws.com/0/348073/c57f033f-92c7-cae1-007c-23f35d2007a1.png)

これならScratch大好き小学生でもすんなり理解できそうですね。ともあれ、この部分はデザインとかセンスの話で、ルールではありません。

このブロックの定義は次の通りです。

![平均ブロックの定義](https://qiita-image-store.s3.amazonaws.com/0/348073/c2bdc7cd-82d8-9448-b99e-704bbc0fde35.png)

このブロックは二つの***値ブロック***の接続点を持っています。それぞれ***Number型***が接続できるようになっています。型を決めておく事により、その接続点には、***Number型***の***output type***を持つ***値ブロック***しか接続できなくなります。ユーザが***String型***のブロックをくっ付けようとしても、繋がりません。

定義が出来たら***save***ボタンもしくは***update***ボタンを忘れずに押しておきましょう。ブラウザのCOOKIEに保存されるようです。(ですので、保存性はあまりあてにならないかも)

さぁこのブロックの動作を定義しましょう。まずは***Generator stub***に表示されているスケルトンコードを見ていきましょう。

```JavaScript
Blockly.JavaScript['average'] = function(block) {
  var value_v1 = Blockly.JavaScript.valueToCode(block, 'v1', Blockly.JavaScript.ORDER_ATOMIC);
  var value_v2 = Blockly.JavaScript.valueToCode(block, 'v2', Blockly.JavaScript.ORDER_ATOMIC);
  // TODO: Assemble JavaScript into code variable.
  var code = '...';
  // TODO: Change ORDER_NONE to the correct strength.
  return [code, Blockly.JavaScript.ORDER_NONE];
};
```

***Blockly Developer Tools***の画面上では、スケルトンコードを閲覧するだけで、改変する事は出来ません、後で、jsファイルにエクスポートしたものを修正する事になります。エクスポートの手順は後述するとして、ここでは、まず動作コードについて考えてみましょう。

二つの接続点に繋がれる値は、このコード内ではそれぞれ***value_v1***、***value_v2***という変数に格納されます。平均ですから、そられを足して2で割ればよいわけですが、そのコードを```var code = '...';```に書いていきましょう。

```JavaScript
 var code = (value_v1 + value_v2)/2;
```

これは間違いです。なぜだか分かりますか？***code***にはコードを文字列として入れなければなりません。では次のコードはどうでしょうか？

```JavaScript
  var code = '(value_v1 + value_v2)/2';
```

これも間違いです。変数はこの時点で展開してやらなければなりません。では正解は何でしょうか？

```JavaScript
  var code = '(' + value_v1 + '+' + value_v2 + ')/2';
```

ちょっとややこしいですが、こんな感じで書きます。もしあなたが、かつてPerlやPHPで動的に変化するJavaScriptプログラム付きのHTMLを吐き出すコードを書いていたら懐かしいと感じるかもしれません。

## 構文ブロックの定義

次は、与えられた値を標準出力に出力する***構文ブロック***を作ってみましょう。

![標準出力ブロック](https://qiita-image-store.s3.amazonaws.com/0/348073/1c53f1f8-9d6c-3e53-c96e-517a4452c898.png)

値を１つ取るブロックで以下のように定義できます。

![標準出力ブロックの定義](https://qiita-image-store.s3.amazonaws.com/0/348073/5305481b-c2e4-66a5-06a0-5bb40ef9c8d9.png)

動作定義コードは次のようになります。（繰り返しになりますが、スケルトンコードを書き換えるのは、次の定義をダウンロードした後になります）

 ```JavaScript
Blockly.JavaScript['console_log'] = function(block) {
  var value_msg = Blockly.JavaScript.valueToCode(block, 'msg', Blockly.JavaScript.ORDER_ATOMIC);
  // TODO: Assemble JavaScript into code variable.
  var code = 'console.log(' + value_msg + ');';
  return code;
};
```

さて、これで、平均値を出力する為の２つのブロックが完成しました。このブロックを使った、***みなさん独自のブロックプログラミング環境***を作ってみましょう。

繰り返しになりますが、Blocklyはブロックプログラミングをする環境ではありません。それに対してScratchはブロックプログラミングをする環境です。Scratch3.0はBlocklyが元になっています。つまり、BlocklyはScratch3.0をぶちのめすような、新たなブロックプログラミングツールを作るためのツールです。（もしくはScratch3.0をHackするにも使えるかもしれませんね。）

## Block Exporter

さて、話が多少前後しましたが、カスタムブロックの定義をダウンロードしましょう。***Block Exporter***タブに切り替えると、３分割された画面が表示されます。

- ***Block Selector***
    - これまでに作ったカスタムブロックのリストです。
- ***Export Settings***
    - エクスポートする定義ファイルのファイル名等を指定します。
- ***Export Preview***
    - エクスポートされる定義ファイルのプレビューです。
 
![Block Exporterタブ](https://qiita-image-store.s3.amazonaws.com/0/348073/d1127cd7-730f-27c8-ff81-ccd9cfcdb507.png)

それでは、***Block Selector***で、平均値出力の為に作った２つのブロックを選択しましょう。次に***Export Settings***の***Block Definitions(s)***と、***Generator Stub(s)***に適当なファイル名を入れます。ここでは次のようにしています。

| | ファイル名 |
| --- | --- |
| Block Definitions(s) | average_blcok.js |
| Generator Stub(s)   | average.js |

ファイル名を指定したら***Export***ボタンを押せば、２つのファイルがダウンロードされますので、適当なフォルダをつくって保存しましょう。

前の節で説明しましたが、動作定義の実装を行わなければなりません、***average.js***を適当なエディタで開いて、***code***の部分を書き換えましょう。

```JavaScript
  var code = '(' + value_v1 + '+' + value_v2 + ')/2';
```

```JavaScript
  var code = 'console.log(' + value_msg + ');';
```

## Workspace Factory

さて、最後のタブ***Workspace Factory***に進みましょう。これまでに、カスタムブロックを作成して、その定義ファイルをダウンロードしました。次に、そのカスタムブロックを含んだ、ブロックプログラミング画面を作りましょう。

![Workspace Factoryタブ](https://qiita-image-store.s3.amazonaws.com/0/348073/5c452d62-d62f-4276-ef1d-e714fd041058.png)

画面右の***Preview***にありますが、ブロックプログラミングの画面はScratchでもおなじみですが、左側に使えるブロックのリスト(ツールボックス - 灰色の部分)、右側がプログラミング領域(ワークスペース - 白い部分)に分かれています。まずはツールボックスを作っていきましょう。

画面中央のアイコン[***+***]ボタンをクリックして***New Category***を選び、新しいカテゴリを作ります。名前を入れろと出てきますので、ここでは仮に***My Blocks***としましょう。（本来ならば、機能別にブロックのカテゴリを分けるべきです。）

また、[***Edit Categry***]ボタンをクリックすると色(Colour)の設定が出来ます。

さて、このカテゴリに所属させるブロックを選びます。***Edit***側のツールボックスにある***Block library***カテゴリに、全てのカスタムブロックが入っていますので、そのうち、使いたい物をワークスペースの方にドラックします。この時デフォルトで組み合わせて表示したいものは、組み合わせても構いませんが、ここでは、平均値算出ブロックと標準出力ブロックの２つを組み合わせずに登録します。

![カスタムブロックの登録](https://qiita-image-store.s3.amazonaws.com/0/348073/d7e896a3-7426-1805-8d13-7ec39799e639.png)

次に、セパレーターを加えてみます。また[***+***]をクリックして、今度は***Separator***を選びます。***My Blocks***の直下に区切り線が引かれました。

これだけですと、カスタムブロック２つしかないワークスペースですので、予め用意されている、基本的なブロックも追加しましょう。[***+***]をクリックして、***Standard Toolbox***を選びます。そうすると、一気に8個のカテゴリが登録されます。

![カスタムブロックを有効にしたWorkspace](https://qiita-image-store.s3.amazonaws.com/0/348073/82d7b936-ae7a-32d6-cf9b-af01ce6b3a2f.png)

さて、次にワークスペースをデザインしていきます。画面左側***Edit***の所にタブが２つあり、今は***Toolbox***という方が選ばれていますね？

![Toolbox,Workspaceタブ](https://qiita-image-store.s3.amazonaws.com/0/348073/36a1d6cb-dbc5-e9c2-2ea1-a552890b8552.png)

これを***Workspace***に切り替えましょう。画面中央に沢山のチェックボックスが表示されます。

![スクリーンショット (93).png](https://qiita-image-store.s3.amazonaws.com/0/348073/f5eab166-bd89-344d-ec40-a49a4162fe46.png)

基本的にはデフォルトのままでも良いのですが、***Zoom***はチェックしておいた方が良いかもしれません。ブロックの拡大縮小が出来るようになります。後は好みですが***Grid***もチェックすると、ワークスペースが方眼紙みたいになります。結果は***Preview***にすぐさま反映されますので、それをチェックしながら調整してください。また***Preview***の***My Blocks***をクリックして、きちんとカスタムブロックが登録されている事も確認しましょう。

![プレビュー画面](https://qiita-image-store.s3.amazonaws.com/0/348073/2cf3e721-9377-b78a-d7f8-bd1a477d0ef5.png)

なお、この画面にはもう一つの機能があります。それは、デフォルトでワークスペースに表示して置くブロックの指定です。

***Edit***側のタブが***Workspace***になっている事を確認して、***Block Library***から***平均値算出の値ブロック***をワークスペースに配置しましょう。

![ワークスペースにカスタムブロックを配置](https://qiita-image-store.s3.amazonaws.com/0/348073/8c4b7069-4a52-db12-8ed2-0a6d738618cf.png)

こうするとプレビューの方にも、反映されます。

![Previewに配置されたカスタムブロック](https://qiita-image-store.s3.amazonaws.com/0/348073/c39ede31-ba5f-1ed5-1595-01def0ec779a.png)

何か、ユーザにデフォルトで提示したいブロックがある場合に使える機能です。

さて、ツールボックスとワークスペースをデザインしましたので、その定義ファイルをダウンロードしましょう。画面上部にある[***Export***]ボタンをクリックして***All***を選びます。

![WorkspaceとToolboxのエクスポート](https://qiita-image-store.s3.amazonaws.com/0/348073/211e15d7-fef4-5322-0ce9-68d577f3496a.png)

ファイルが３つ順番にダウンロードされます。保存するファイル名を聞かれますが、デフォルトのままで良いでしょう。さて、これで全ての定義ファイルがダウンロードできました。

![定義ファイル一式](https://qiita-image-store.s3.amazonaws.com/0/348073/3687fae0-08c0-7894-cc02-a5e4ba2793ec.png)

## ブロックプログラミング画面の作成

ここまでの手順で定義ファイルが全て揃いましたが、肝心のHTMLファイルがありません。Scratchのように、ユーザはブラウザ上でブロックプログラミングをしますので、その画面はHTMLページとして書かなければなりません。最後にそれを作ってみましょう。

大まかな手順としてはHTMLファイルを作って、そこに、これまでにダウンロードしたファイル群を読み込んでいきます。ブロック定義に関しては***average.js***と***average_blcok.js***ですので```<script>```で読み込めばOKです。***workspace.js***はツールボックスやワークスペースを画面上に配置するメインのプログラムですので、お好みに応じて```<script>```で読み込むか、HTMLファイルの中にコピペ移植すれば良いでしょう。

問題はXMLファイルです。画像・動画・JavaScript・CSSはタグを使って簡単に読み込めますが、XMLファイルはできません。Ajaxを使ったりと、すこし手間がかかります。それが原因かどうかは分かりませんが、 [公式ページでは、「XMLファイルはHTMLのどこかに直接埋め込んどいてね」](https://developers.google.com/blockly/guides/configure/web/fixed-size) と書いてあります。

私も、埋め込んで作っていましたが、この定義、非常に長くなって、メンテナンス性が悪い上、***Blockly Developer Tools***からエクスポートしたそのままの状態で使えるものですので、何とか、外部ファイルとしておきたい。

という事で、Ajaxよりも最近の規格である***Fetch API***を使って読み込んでみようと思います。

## index.htmlの実装

では、まず***index.html***を作ってみましょう。ブロック定義・ワークスペース定義・ツールボックス定義ファイルのあるフォルダに、***index.html***を作ります。エディタは何でも構いませんが、***Fetch API***をテストするのにWebサーバが必要になります。 [Microsoft Visual Studio Code](https://code.visualstudio.com/) なら、ボタン一発でWebサーバが立ち上がりますのでオススメです。

まずはHTMLの雛形を作りましょう。

```html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>My Custom Blocks - Blockly</title>
</head>

<body>

</body>

</html>
```

まぁ誰が作ってもこんな感じですね。

HTMLとして必須なのは、ユニークなIDの付いた```<div>```です。その```<div>```の中にツールボックスとワークスペースが表示されます。この記事はあくまで習作の解説という事で、デザインなんてどうでもよいのですが、それでもサクッと綺麗なページが作れる***Bootstrap***を使ってデザインしましょう。ページを左右で分割して、左側にツールボックスとワークスペース、右側はプログラムの実行ボタンと、確認の為のJavaScriptコードを表示するボタンを作りましょう。(それら機能の実装は後で説明します。)

下記に ```<body>```内のサンプルコードを示します。

```html
    <div class="container">
        <div class="row">
            <div class="col-8" id="blocklyDiv"></div>
            <div class="col-4">
                <button id="showCode" class="btn btn-success">JavaScriptを表示する</button>
                <button id="execCode" class="btn btn-primary">実行する</button>
                <pre id='jsCode'></pre>
            </div>
        </div>
    </div>
```

```<div>```のid属性に設定した値は後々使いますので覚えておきましょう。特にプログラミング画面のid(```blocklyDiv``` )は重要です。

次に、```<head>```タグも作っていきましょう。まずはBootstrap関連から。CSSファイルとJavaScriptファイルをリンクします。JavaScriptの方は、 [Bootstrap Native](https://thednp.github.io/bootstrap.native/) の方に差し替えています。jQueryフリーのバージョンで、ほぼ普通のBootstrapと互換性があります。

```html

    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
        crossorigin="anonymous">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap.native/2.0.15/bootstrap-native-v4.min.js"></script>
```
いずれもCDN (Content Delivery Network) から読み込みますので、何かをダウンロードしたりする事は不要です。

次にBlockly関連のファイルをリンクします。まずは基本機能と基本ブロックの定義をリンクしましょう。

```JavaScript
    <script src="https://cdn.jsdelivr.net/gh/google/blockly@latest/blockly_compressed.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/google/blockly@latest/blocks_compressed.js"></script>
```

次に、ブロックプログラミングのエクスポート先の言語に関連したJavaScriptファイルもリンクします。今回はJavaScriptのみなので以下のファイルをリンクするだけでOKです。ちなみに、他には、***python_compressed.js***、***php_compressed.js***、***dart_compressed.js***、***lua_compressed.js***があります。他の言語にもエクスポートする際は、必要に応じてリンクを加えてください。もちろんカスタムブロックの動作定義も、複数言語に対応しなければなりません。

```HTML
    <script src="https://cdn.jsdelivr.net/gh/google/blockly@latest/javascript_compressed.js"></script>
```

次も言語の設定なのですが、こちらは自然言語の方です。様は日本語・英語というような切り替えです。Scratchも沢山の言語に対応していますが、Blocklyも多くの言語に対応しています。今回は日本語ですので以下のようになります。

```html
   <script src="https://cdn.jsdelivr.net/gh/google/blockly@latest/msg/js/ja.js"></script>
```

もし、バスク語版を作りたければ、URLを変えるだけです。

```html
   <script src="https://cdn.jsdelivr.net/gh/google/blockly@latest/msg/js/eu.js"></script>
```

次に、カスタムブロックの定義ファイルをリンクします。

```html
    <script src="./average_block.js"></script>
    <script src="./average.js"></script>
```

さらに、残るファイル***workspace.js***をリンクしましょう。このJavaScriptファイルがメインですので、他のJavaScriptファイルやHTMLファイルが読み込んだ後に実行するように***defer***属性を付けておきましょう。

```html
   <script src="workspace.js" defer></script>
```

最後に、```<div>```タグの高さをCSSで規定しておきましょう。とりあえずは画面いっぱいに表示したいので、以下の様なCSSをページに追加しておきます。

```html
    <style>
        #blocklyDiv {
            height: 100vh;
        }
    </style>
```

これでHTMLは完成です。では早速これをブラウザで見てみましょう。ローカルファイルとして直接ブラウザで開いても(この時点では)問題ありませんが、折角ですのでWebサーバ経由で見てみましょう。

Visual Studio Codeを使っている場合、Webサーバの立ち上げは簡単です。HTMLファイルのあるフォルダを開いた状態で、画面下の方にある***Go Live***というボタンをクリックすルだけで、WebサーバとWebブラウザが立ち上がります。

![Go Liveボタン](https://qiita-image-store.s3.amazonaws.com/0/348073/41840dcc-cf72-b5fc-034e-12bf8b2cba6e.png)

ブラウザに*http://127.0.0.1:5500/index.html*が表示されていると思いますが、この時点ではエラーが出て、うまく表示できません。エラーはChromeの場合は***F12***キーで出てくるデベロッパーツールで見られます。

![エラーの表示](https://qiita-image-store.s3.amazonaws.com/0/348073/9aead06e-5d55-af60-2638-853a7a62d694.png)

なお、Visual Studio Code使っていない場合で、ご使用のエディタに同様なWebサーバ機能が無い場合は、Chromeの拡張機能を使う手があります。

[Web Server for Chrome](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=ja)

## workspace.js

さて、エラーがでてしまいましたが、実は***workspace.js***は、この時点では、まだ未完成です。ではエラーの出ている36行目を見てみましょう。

```JavaScript
/* Inject your workspace */ 
var workspace = Blockly.inject(/* TODO: Add ID of div to inject Blockly into */, options);
```

なにやら***ToDo***が潜んでいました。ここの部分に```<div>```のIDを入れましょう。

```JavaScript
/* Inject your workspace */ 
var workspace = Blockly.inject('blocklyDiv', options);
```

さらにHTMLタグではリンクできないXMLファイルもJavaScriptのFetch APIを使ってページ内に読み込むようにしましょう。

Fetch APIの解説は [MDNにあります](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch)
。

そこで例示されているコードを見てみましょう。

```JavaScript
fetch('http://example.com/movies.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(JSON.stringify(myJson));
  });
```
なるほど。通信は非同期で行われますが、***Promise***に従って、***then***で繋いでいくことで、順序処理を書けるようになっています。

では、こんな戦略でソースコードを作っていきましょう。

```JavaScript
Promise.all(
    //ToDo: 全てのXMLファイルの読み込み
).then(
    //ToDo: XMLをDOMツリーに加える
).then(
    //元々workspace.jsにあった処理をここへ
);
```

ではまずXMLファイルを読み込む部分を作りましょう。読み込みたいXMLファイルを羅列して、それぞれに対して同じ処理をする訳ですから```Array.map()```を使うと良いでしょう。

```JavaScript
Promise.all(
	["workspace.xml", "toolbox.xml"].map(async file => {
		return fetch(file).then(
			(res) => {
				return res.text();
			}
		);
	})
)
```

XMLファイルのパスは配列に入れておき、それをmapします。反復処理の部分は、XMLファイルのパスが***file***変数として渡されますので、```fetch(file)```として、そのパスのファイルを持ってきます。レスポンスが***res***に格納されて帰ってきますので、その中のbody部分、すなわちXML文書を```res.text()```で抜き出して返します。なお、この```res.text()```はPremiseですので、```map()```はXMLファイル数分のPromiseの配列を返します。```promise.all()```は複数のPromiseを入力にとり、全て解決している場合、単一のPromiseを返します。

つまり、XMLファイルが全て読み終えた段階で、最初の```then()```に処理が移ります。XMLファイルが読み終わりましたので、最初の```then()```では、XMLをHTMLのDOM(```<body>```の直下)にくっつけます。

```JavaScript
then((xmls) => {
	xmls.forEach((xml) => {
		var parser = new DOMParser();
		var doc = parser.parseFromString(xml, "application/xml");
		document.body.appendChild(doc.documentElement);
	});
})
```

これで、XMLファイルをJavaScriptから参照できるようになったので、あらかじめworkspace.jsのコードを二番目の```then()```に入れましょう。

長くなるので省きますが、完成したworkspace.jsのコードはGISTに置いたので見てください。

https://gist.github.com/abarth500/375950acbe5ae18942bcb50b927355ef

さぁ、これでもう一度、ブラウザでindex.htmlを見てください。なお、かならずWebサーバ経由で見てください。Visual Studio Codeのgo liveを使っている場合は http://127.0.0.1:5500/index.html です。

成功すれば以下の様なWebページが表示されます。

![スクリーンショット(初期画面)](https://qiita-image-store.s3.amazonaws.com/0/348073/06ef1785-28b9-a454-7987-f5795e241df3.png)

## はじめてのブロックブログラミング

さて、できた事とできていない事をまとめておきましょう。

- できた事
    - カスタムブロックの定義(構文ブロック・値ブロック)
    - ツールバーの定義
    - ワークスベースの定義
    - 定義ファイルの読み込み
    - プログラミング環境の構築
- できていない事
    - ブロックプログラムをJavaScriptにエクスポート
    - ブロックプログラムの実行
   
では、一つずつ潰していきましょう。まずはワークスペースに作ったブロックからJavaScriptコードを吐き出す部分です。

### JavaScriptコードのエクスポート

ワークスペースはworkspace.js内で```workspace```変数で保持しています。これをJavaScriptコード(の文字列)に変換するには、```workspaceToCode```関数を使います。

```JavaScript
Blockly.JavaScript.workspaceToCode(workspace);
```

ここで得られたコードを***index.html***で定義している```<pre>```タグに突っ込めば、画面にJavaScriptコードを表示できます。コードは***workspace.js***の二番目の```then()```の中の末尾に加えていきましょう。
 
```JavaScript
const pre = document.getElementById('jsCode');
pre.innerHTML = Blockly.JavaScript.workspaceToCode(workspace);
```

なお、もう一つ、無限ループの取り扱いを先に指定しておかなければいけないようです(未検証)。とりあえず以下のようにしてお来ましょう。

```JavaScript
Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
```

余談ですが、公式ドキュメントでは次のようなコードを推奨しています。( [詳しくこちらを参照](https://developers.google.com/blockly/guides/app-integration/running-javascript#infinite_loops) )

```JavaScript
window.LoopTrap = 1000;
Blockly.JavaScript.INFINITE_LOOP_TRAP = 'if(--window.LoopTrap == 0) throw "Infinite loop.";\n';
var code = Blockly.JavaScript.workspaceToCode(workspace);
```

グローバルスコープでカウンターを用意して、ループの中でカウンターを減らしていき0になったら、エラーを吐いて止まるという仕組みの様で、おそらく```INFINITE_LOOP_TRAP```は、ループの中に自動的に展開されるコード断片ではないでしょうか(未検証)。1000で十分なのかどうかはよくわかりませんが、実際に何かを作る時は、考慮すべきかもしれません。

さて、最後に、ここで作ったJavaScriptのソースコード表示機能を、ボタンに割り当てます。***index.html***には```id="showCode"```というボタンがあるので、それに割り当てましょう。全体のコードを以下に示します。

```JavaScript
function showCode() {
    Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
    const pre = document.getElementById('jsCode');
    pre.innerHTML = Blockly.JavaScript.workspaceToCode(workspace);
}
document.getElementById('showCode').addEventListener('click', showCode, false);
```

では、もう一度Webブラウザに戻って、ページを更新してみてください。ワークスペースには、何も接続されていない平均算出の***値ブロック***が一つ表示されています。

![平均ブロック](https://qiita-image-store.s3.amazonaws.com/0/348073/c57f033f-92c7-cae1-007c-23f35d2007a1.png)

では、この状態で[***JavaScriptを表示する***]をクリックしてみましょう。その下に以下の様に表示されたと思います。

```text
(+)/2
```

Blocklyは文字列の切った貼ったをするだけなので、もし接続点になにもくっついていない場合、空文字、nullとして評価されるようです。(undefinedでエラーも出ません)

本来なら、必須フィールド等の設定があると便利なのですが、***Blockly Developer Tools***ではそのような設定は出来ないようです。ただ、 [Blockly.Fieldクラス](https://developers.google.com/blockly/reference/js/Blockly.Field)のコンストラクタの引数に```opt_validator```というのがあるので、自分で値の検証をする事が出来るのかもしれません(未検証)。

では、数値を接続点に入れてみましょう。数値は***Math***カテゴリにあります。ただ単に数値を入れるだけだと面白くありませんので、数値を吐き出すブロックでしたら他のブロックを接続しても構いません。例えばここでは***平方根***のブロックも接続してみます。

![平均値の算出例](https://qiita-image-store.s3.amazonaws.com/0/348073/395de95a-f2f7-fc07-69d2-e113bf296a55.png)

これに対して[***JavaScriptを表示する***]をクリックすると次のコードが表示されます。

```text
(15+(Math.sqrt(9)))/2;
```
やっと式らしくなってきました。ただし、まだこれでは『プログラム』にはなっていません。最後にこの値を標準出力に出力しましょう。

***My Blocks***カテゴリから標準出力ブロックを引き出して、平均値ブロックに接続してください。

![平均値を標準出力に出力するプログラム](https://qiita-image-store.s3.amazonaws.com/0/348073/fe623e9e-b4f8-bd66-ceda-aee7688e4446.png)

さぁ、これでJavaScriptコードを見てみましょう。

```JavaScript
console.log(((15+(Math.sqrt(9)))/2))
```

やっと、実行できそうなコードが出てきました。ただ、実際にはQiitaのようにソースコードに色付けされないので、白地に黒字の味気ないソースコードが表示されました。

![ソースコードの表示(ハイライトなし)](https://qiita-image-store.s3.amazonaws.com/0/348073/ad6627df-57d8-ac0d-d2fb-2ab7b35e6d5e.png)


### Syntax Highlighter

完全に脱線ですが、ソースコードの色付けもやってみましょう。ソースコードの色付けは***Syntax Highlighter***と呼ばれる機能で、ここではその中でもJavaScriptから使いやすい***highlighter.js***を使ってみましょう。更新するファイルは***index.html***と***workspace.js***です。

まずは***index.html***の```<head>```で、CSSとJavaScriptを読み込んで起動しましょう。```<title>```のすく下に以下の3行を足します。

```html
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/atom-one-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
```

CSSファイルを差し替えると、コラースキームを変える事が出来ます。対応言語とカラースキームのリストは以下のデモページとCDNのページを見てください。

- デモページ：https://highlightjs.org/static/demo/
- CSSファイルURL一覧：https://cdnjs.com/libraries/highlight.js/

また、```<pre>```もすこし改良しましょう。```<pre>```の中に```<code>```を加えます。```id='jsCode'```も```<code>```の方に付け替えます。

```html
<pre><code class="JavaSciprt" id='jsCode'></code></pre>
```

次に***workspace.js***を修正します。```showCode()```関数の末尾に以下のコードを付け加えてください。

```JavaScript
hljs.highlightBlock(pre);
```

コードの色付けは静的に行われるため```<pre>```を書き換えたタイミングで```hljs.highlightBlock()```関数を呼んで、明示的に色付けをしてやらなければなりません。

さぁ、これで次のような色付けされたJavaScriptコードが表示されるようになったと思います。

![ソースコードの表示(ハイライトあり)](https://qiita-image-store.s3.amazonaws.com/0/348073/59bc8635-4793-3ca6-264d-b54ae876d708.png)


### プログラムの実行

ついに、プログラムを実行できるところまでやってきました。今回の実行言語はJavaScriptで、さらに前節で、ブロックをJavaScriptコードの文字列に変換する機能が完成しました。後は単にそのJavaScriptコードを```eval()```関数に渡して、実行してもらうだけです。では、実行の機能を[***実行する***]ボタンに割り当てましょう。

```JavaScript
	function execCode() {
		Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
		try {
			eval(Blockly.JavaScript.workspaceToCode(workspace));
		} catch (e) {
			alert(e);
		}
	}
	document.getElementById('execCode').addEventListener('click', execCode, false); 
```

さぁ、Webブラウザで[***実行する***]ボタンを押してみましょう。

![標準出力](https://qiita-image-store.s3.amazonaws.com/0/348073/caa0c957-c342-b414-80e5-054fc2be7fdc.png)

どうですか？標準出力に***9***と出力されたでしょうか？こんだけ長いページを読んできた末の成果物としてかかなり地味ですが、二つの数値をとって平均値を標準出力に出すカスタムブロックがきちんと動作しました。

折角ですから、元々あるブロックとも組み合わせてみましょう。

![拡張したプログラム](https://qiita-image-store.s3.amazonaws.com/0/348073/1651eeb2-b8af-97ce-f97a-7be8b1b4034b.png)

平均値を変数に代入しておき、それを標準出力に出力すると共に、元々あるアラートで表示する機能を使って、表示しています。

![スクリーンショット (113).png](https://qiita-image-store.s3.amazonaws.com/0/348073/563aa68d-29cb-03d5-d165-1e63607917f5.png)

この様なアラートが出てきましたか？

今回はここまでにしておきます。長い記事ですので、ここまで読んでくださった方、大変ありがとうございます。私自身あまりにも記事が長すぎで息切れししております。この記事が、MITのScratchをぶちのめす何かをつくる一助になれば幸いです。

# この記事のまとめ

WebSocketの実装について解説しようと思っていましたが、全然そこまでたどり着きませんでした。まずはBlocklyでカスタムブロックをどのように作るのか、そしてそれを使ったブロックプログラミング環境をどう作るのかの説明は、一通りできたと思います。

次回は、WebSocketをブロックとして実装する所の解説をします。