blockly-samples icon indicating copy to clipboard operation
blockly-samples copied to clipboard

"Uncaught TypeError: global is undefined" when using custom Blockly modules with Parcel

Open lypwig opened this issue 4 years ago • 7 comments

Describe the bug

When using custom Blockly modules with Parcel, I get the error Uncaught TypeError: global is undefined.

To Reproduce

  1. I forked the blockly-samples repository, then cd blockly-samples/examples/blockly-parcel, and npm install;
  2. npm start -> Parcel builds the app successfully, and the Blockly app on the local web server is working;
  3. 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).
  4. Then I imported the local Python generator instead the built-in Python generator, and added the google-closure-library to requirements (to avoid a goog is not define error) (74338a5).
  5. npm start -> Parcel still builds the app successfully, but this time I get the error Uncaught TypeError: global is undefined.

Expected behavior

Blockly Parcel app should work with a custom local generator.

Screenshots

image

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.

lypwig avatar Jul 25 '21 23:07 lypwig

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 =)

BeksOmega avatar Jul 26 '21 17:07 BeksOmega

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.

2torus avatar Jul 26 '21 20:07 2torus

Replace goog.require with import and goog.provide with export.

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.

lypwig avatar Jul 26 '21 23:07 lypwig

Am I supposed to use a plugin like parcel-plugin-closure?

lypwig avatar Jul 27 '21 11:07 lypwig

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!

BeksOmega avatar Jul 27 '21 22:07 BeksOmega

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.

2torus avatar Jul 30 '21 16:07 2torus

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.require with import and goog.provide with export.

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.

2torus avatar Jul 30 '21 19:07 2torus