"Uncaught TypeError: global is undefined" when using custom Blockly modules with Parcel
Describe the bug
When using custom Blockly modules with Parcel, I get the error Uncaught TypeError: global is undefined.
To Reproduce
- I forked the blockly-samples repository, then
cd blockly-samples/examples/blockly-parcel, andnpm install; npm start-> Parcel builds the app successfully, and the Blockly app on the local web server is working;- then I added the Python generator locally, based on the Python generator in the blockly repository, as a temporary step to create and use my own generator (397de71).
- Then I imported the local Python generator instead the built-in Python generator, and added the
google-closure-libraryto requirements (to avoid agoog is not define error) (74338a5). npm start-> Parcel still builds the app successfully, but this time I get the errorUncaught TypeError: global is undefined.
Expected behavior
Blockly Parcel app should work with a custom local generator.
Screenshots

Desktop:
- OS: Debian
- Browser: Firefox
- Version: 90
Stack Traces
Uncaught TypeError: global is undefined
["4zfCE"]< nodejs.js:49
newRequire generator.54de7a8f.js:71
localRequire generator.54de7a8f.js:83
["2PZRm"]< generator.js:11
newRequire generator.54de7a8f.js:71
<anonymous> generator.54de7a8f.js:120
<anonymous> generator.54de7a8f.js:143
nodejs.js:49
["4zfCE"]< nodejs.js:49
newRequire generator.54de7a8f.js:71
localRequire generator.54de7a8f.js:83
["2PZRm"]< generator.js:11
newRequire generator.54de7a8f.js:71
<anonyme> generator.54de7a8f.js:120
<anonyme> generator.54de7a8f.js:143
InnerModuleEvaluation self-hosted:2381
evaluation self-hosted:2332
If I follow the stacktrace, this error seems to be trigered by this line in the google closure library.
Hi @2torus , have you run into any issues like this? Or have tips for where to start looking for a fix? Just sending a ping because you have more experience with Parcel than any of the people on the core team hehe.
Also thanks for filing this issue @roipoussiere =)
I don't think you can mix parcel with google closure and you don't need to. Replace goog.require with import and goog.provide with export.
Replace
goog.requirewithimportandgoog.providewithexport.
Ok, so I tried this on my fork (5d66898), could you quickly check in the diff if the modifications on the imports and exports seem good for you?
But anyway, I get the same error (Uncaught TypeError: global is undefined), because goog is still used by the blockly dependency.
Am I supposed to use a plugin like parcel-plugin-closure?
Am I supposed to use a plugin like parcel-plugin-closure?
I'm not sure, but it seems like it would be worth a shot! If you do give it a try, we'd love to know how it works out.
I don't know anything about bundlers, but you might also want to try using the Blockly via npm (instead of a fork), and then using the import and export keywords for your own code (like @2torus suggested). That way you can get rid of the closure stuff entirely.
But again, I'm pretty out of my depth here hehe. If there's anything I can do to help don't hesitate to reach out!
Am I supposed to use a plugin like parcel-plugin-closure?
I don't believe it will work. It is intended for Closure compiler and not for Closure library.
There is a more fundamental issue here. You are trying to arrange things the way closure library works and it's not compatible with parcel. Closure library is sticking attributes into global or semi-global objects like Blockly. It's very brittle and frowned upon in modern software development. While you can still make it work with parcel, you don't need to.
A proper way to do things is to subclass Blockly.Generator class and add block definitions as methods. I'm doing it with my project.
The bad news is since Blockly.Python is not written that way you can't re-use any of the Blockly.Python code without rewriting most of it properly.
I saw that you opened #830 for this but that's the gist of the idea without doing the actual work.
Replace
goog.requirewithimportandgoog.providewithexport.Ok, so I tried this on my fork (5d66898), could you quickly check in the diff if the modifications on the imports and exports seem good for you?
But anyway, I get the same error (
Uncaught TypeError: global is undefined), becausegoogis still used by theblocklydependency.