How to generate a minimized binary for embedded use with Closure Compiler? goog and Blockly are undefined during advanced compilation

98 views
Skip to first unread message

関根史人

unread,
Jun 16, 2025, 11:42:08 AMJun 16
to Blockly

Hi, I'm trying to build a minimized version of Blockly for use on an embedded device. I'd like to reduce the final JavaScript size as much as possible—ideally under 100 KB as suggested in the official Blockly Advanced Compilation guide.


Goal:

Create a very small binary of Blockly (ideally ~100 KB or less) to use on a resource-constrained embedded device.


What I tried:
  1. I cloned the latest master branch from Blockly GitHub.

  2. I ran npm run package inside the Blockly directory.

  3. It generated JavaScript files inside build/src/.

  4. I then attempted to run Closure Compiler with the following command:

bash
CopyEdit
java -jar closure-compiler.jar --js='main.js' \ --js='blockly/build/src/blocks/**.js' \ --js='blockly/build/src/core/**.js' \ --js='blockly/build/src/generators/**.js' \ --generate_exports \ --compilation_level ADVANCED_OPTIMIZATIONS \ --dependency_mode=PRUNE --entry_point=Main \ --js_output_file main_compressed.js

Note: I removed --externs ../externs/svg-externs.js because the file doesn't exist in the repo.


Problem:

I get the following errors:

css
CopyEdit
main.js:1:0: ERROR - [JSC_UNDEFINED_VARIABLE] variable goog is undeclared goog.provide('Main'); ^^^^ main.js:15:2: ERROR - [JSC_UNDEFINED_VARIABLE] variable Blockly is undeclared Blockly.inject('blocklyDiv', { ^^^^^^^

So it seems that Closure Compiler doesn't recognize the goog or Blockly symbols.


Questions:
  1. What is the correct way to compile Blockly using the Closure Compiler for minimal output?

  2. Where can I find the missing svg-externs.js file mentioned in the documentation?

  3. The doc also refers to core/requires.js—this file no longer exists in the repo. What is the recommended alternative?


Any help or updated instructions would be greatly appreciated. Thanks in advance!

関根史人

unread,
Jun 16, 2025, 11:42:09 AMJun 16
to Blockly

Maribeth Moffatt

unread,
Jun 16, 2025, 4:04:06 PMJun 16
to Blockly
Hi,

In order for advanced compilation to work, the rest of your application that interacts with Blockly also needs to be compiled with Closure Compiler. The way that advanced compilation works is it will compile Blockly + your application code together, so that the compiler can rename Blockly functions to smaller names and then rename your usage of those functions as well. Plus, it will remove functions that aren't used at all, and inline others.

If you don't compile your application together with Blockly using Closure Compiler then it won't be safe to remove the code or rename certain objects. But setting up your application to work with closure compiler is not a trivial task and it's not something the Blockly team can help you with -- you'd have to refer to the closure compiler docs. You have to annotate your code in certain ways, and be very strict about calling code outside that which is compiled by closure compiler. Also, getting closure compiler to work with typescript was an adventure Christopher could describe to you for hours probably, but again, not something we can provide support for.

So before I dive too deeply on this topic, can you confirm that is something you actually want to do?

If you don't compile the rest of your code with closure compiler, then you should just use the published version of blockly. We already compile and minify it as much as is safe to do so (e.g. minifying internal variables without changing exported function names). Another alternative that is probably simpler to set up as it is more popular with the rest of the internet is using a more popular compilation tool like webpack or one of your choice. Those tools will also be able to tree-shake Blockly to some extent, and you could play with using the uncompiled version of Blockly to see if that gives you better tree-shaking results.

Our docs on the topic are a bit out of date, as you've noted. If you want to know how our current setup works, you can poke around our advanced compilation test and our gulpfiles that call the closure compiler.

We can give a few more pointers either way, but do let us know more details about the rest of your application + build system first so that we can provide more relevant help.

Best,
Maribeth

Max Stephen Russell

unread,
Jun 16, 2025, 4:31:52 PMJun 16
to Blockly
This is a shining example of why I greatly admire and appreciate the Blockly Team, their work ethic, and their strenuous support of their brand.

-Steve Russell

関根史人

unread,
Jun 17, 2025, 11:30:05 AMJun 17
to Blockly

Hi Maribeth,

Thank you very much for your thorough and thoughtful reply — I really appreciate your detailed explanation and the time you took to write it.

To answer your question: yes, I do want to pursue advanced compilation or any other effective method to significantly reduce the size of Blockly. However, the real goal behind this is not just understanding how compression works, but rather obtaining a minimal and optimized build of Blockly that is usable in a highly resource-constrained environment.

Here’s the background:

I’m building a Blockly-based interface that will run on an embedded device mounted on a robot. The embedded device hosts a small web server and serves a Blockly UI to client tablets (like iPads or Android tablets) connected over Wi-Fi. This setup must work entirely offline — no CDN or external assets.

The controller of the embedded system has only 8MB of flash storage (shared with other app components). The pre-built blockly_compressed.js file from the v12.1.0 release is around 1MB, which is quite large for our case.

From my testing, this 1MB file takes about 4–5 seconds to load due to slow I/O on the device. If we could reduce this to 100KB or less, it would not only fit more comfortably in flash, but also reduce load time to under a second — a huge improvement in UX. I am even considering migrating to a 4MB flash chip to reduce manufacturing cost, so minimizing the binary size is essential.

What I’m hoping for is any advice or a path forward to obtain the smallest practical build of Blockly that retains only the features I need (e.g., a limited set of blocks and generators). If that means diving into Closure Compiler configuration, I’m willing to go that route — but if there are examples, templates, or even partial automation (like a script that prunes unused components), that would be incredibly helpful.

Thanks again,

Fumito Sekine


2025年6月17日火曜日 5:31:52 UTC+9 maxsr...@gmail.com:

Neil Fraser

unread,
Jun 17, 2025, 11:47:47 AMJun 17
to blo...@googlegroups.com
FYI: Blockly Games is also highly sensitive to size and performance on low-end systems.  The result of our extremely extensive testing is that Blockly grew 6x in size as a result of its conversion to TypeScript.  That is why Blockly Games is permanently pegged to a fork of Blockly from November 2021.  It uses Closure Compiler's advanced compilation to obtain a total memory footprint of 250 kb for Blockly and the game's own JavaScript.  This could be reduced further if unneeded components are deleted.

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/blockly/0a58534c-93d6-477c-a385-8b45f322f5c3n%40googlegroups.com.


--
Neil Fraser, Switzerland
https://neil.fraser.name

Maribeth Moffatt

unread,
Jun 17, 2025, 2:49:37 PMJun 17
to Blockly
Using advanced compilation requires that the rest of your application also use Closure Compiler for advanced compilation. That's the part I'm not sure about from your description. If you just run advanced compilation on Blockly in isolation, your output will be nothing! This is because advanced compilation removes unused code, and if you haven't actually *used* Blockly in your application code you're compiling, then it's all unused and safe to remove. 

Therefore, you'll need to set up the rest of your application to be compilable with Closure Compiler. There is a lot of good information on their GitHub page. The thing I want to draw your attention to is their recommendation that Closure Compiler only be used on JavaScript code that has been specifically written for the Closure Compiler. This imposes certain restrictions on your code that you must adhere to in order for advanced compilation to work. For example, it is recommended to use the Closure library's goog.module and goog.require statements instead of using esmodules or cjs modules. However, the Closure library (which is separate from the Closure Compiler) has been deprecated and archived. While these functions (goog.module and friends) live on in the closure compiler code, there are no longer any codelabs or much usable documentation about how they work, so you'll have to rely on reading the code or maybe you can find some outdated examples to follow. Generally, the Closure Compiler team's view seems to be that it may not be the correct choice for a new project with handwritten JavaScript. They recommend using TypeScript, but there's not documentation that I can find about how to enable advanced compilation on the compiled typescript output.

Once the rest of your application is written with Closure Compiler in mind, you can include the Blockly sources in with your compilation. I would recommend using our advanced compilation test which I linked to above as a guide for the arguments to pass to the closure compiler.

---

Thanks for providing some additional context, Neil! Note that if you wish to follow in Blockly Games's footsteps, you'll still have to deal with the above to get Blockly to that size. It will make it harder for us to answer questions about how advanced compilation works as we don't generally support much older versions like that, so if you go that route, looking at how Blockly Games is set up might be easier than looking at Blockly's advanced compilation test for an example. However, you will miss out on new features in Blockly that we encourage you to use such as our recent improvements to keyboard navigation and our upcoming compatibility with screenreaders.

Reply all
Reply to author
Forward
0 new messages