LoginSignup
10
3

More than 3 years have passed since last update.

TypeScriptとBlocklyとnpmと

Last updated at Posted at 2020-08-12

自己紹介

そのへんほっつき歩いてる高専生。
普段は課題に追われながらラーメン食っている。
GitHub: isso0424
Twitter: kousou4129

何があったか

  • TS + Blockly + ElectronWebpack + Electron + Reactで開発してた
  • Blockly.JavaScriptが使えない!!!
  • 直すぜ!!!

簡単な話Generatorが見つからなくて怒られた。
いつの間にか僕がキレてた。

注意

  • 今回の記事はScriptタグを使用できない状況の話です。
  • 普通ならScriptタグで読み込めば終わります。
  • 筆者はWebpackの再設定で諦めました
  • 7時間かけて解決したので最後の方はヤケクソです。

というわけで原因究明

まずは原因を辿ることから開始。
とりあえず以下を実行

console.log(Blockly.JavaScript)

結果: undefined

はい、見つからん。

Generator捜索

Blockly.JavaScriptはJavaScript用のBlocklyのGeneratorです。
という訳で私はGeneratorの定義元を探しにアマゾン(node_modules)の奥地に向かいました。

Blockly.Generator.JavaScriptとの出会い

アマゾンを捜索しているとjavascript.jsというファイルを発見!!!

というわけで中を読んでみる

javascipt.js(一部抜粋)
Blockly.JavaScript = new Generator("JavaScript");

おおおおおお!!!!!全世界が求めたコードが!!!!
早速importしてみる

Uncaught ReferenceError: goog is not defined

あ゛あ゛あ゛あ゛あ゛あ゛あ゛あ゛あ゛あ゛!!!!!!
でもこれ解決すればいけそう!!!
INSTALLLLLLL

yarn add goog

よし!!!通れ!!!

Uncaught ReferenceError: goog is not defined

え...

問題点

blockly/generators/javascriptgoogというライブラリが使われているのだが、こいつがなんか駄目らしい。

再びアマゾンの奥地へ

さてgoogに対して明確な殺意を持ったところで解決策を探していく。
ggっているとこんな記述を多く見た。

<script src="javascript_compressed.js"></script>

な ん だ こ の ふ ぁ い る

javascript_compressed.jsの正体

どうやらリファレンスによるとこいつがjavascript用のgeneratorを担っているらしい。

ということはこいつ、使えるのでは?

新たなる問題

さてここで新たな問題が発生。
今回Blockly.JavaScriptの形で今までのコードが書かれているのでなんとかこいつをBlockly配下に持っていきたいのである。
しかし、それをしようにもBlocklyにTypeScriptにおける.JavaScriptへの型定義が用意されていないので書くのが面倒だ。

黒魔術

TSには実は黒魔術が存在する。
それは(Hoge as any)だ。
これを利用することでどんなオブジェクトでもanyにみなしていじくり回せるのである。

これ、importしてきたものも例外ではなく、型定義を無視して好き勝手なプロパティを生やすことができる。

黒魔術2

またもやTSの黒魔術の話になる。
お次の黒魔術はrequireである。
これ、何でもかんでもanyでimportできるのである。

と い う わ け で

これにより解決策が見いだせた。
javascript_compressedに黒魔術を振りかけるとこうなる。

import * as Blockly from "blockly/core";
(Blockly as any).JavaScript = require("blockly/javascript_compressed");

黒魔術通り越してクソコード

検証タイム

検証方法

以下のコードを用いて実験した。

(Blockly as any).JavaScript.Hoge = (block: any) => {
  return "console.log("hoge");"
}

console.log((Blockly as any).JavaScript.Hoge());
// blockly/generators/javascript.jsで定義されている定数を実験に使用
// デフォルト値は1.1
console.log((Blockly as any).JavaScript.ORDER_NEW);

結果

console.log("hoge");
1.1

!!!!!
これは!!!!!待ちに待った成功というやつか!!!!

まとめ

  • npmパッケージのBlocklyはちょっと不親切なところがあるので注意する
  • コードリーディングは最強
  • anyは程よく使えば都合良いヤツ 型定義は面倒
  • そもそもwebpack勉強してScriptタグで解決したほうが生産的

知見を得たり、役に立ったりしたら、LGTMお願いします!!!

10
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3