Blockly plugins - Importing issue

309 views
Skip to first unread message

PilotTim136

unread,
Mar 22, 2024, 2:19:54 PM3/22/24
to Blockly
I can't import plugins properly (blockly-dark mode) because if i use the way it says (with the import darkTheme * from "@blockly/theme-dark") it doesn't work for some reason.
it responds with a 404 value

<script>
        import * as Blockly from 'blockly';
        import DarkTheme from '@blockly/theme-dark';
        Blockly.inject('blocklyDiv', {
            theme: document.getElementById('theme'),
            toolbox: document.getElementById('toolbox'),
        });
    </script>

and it doesn't work for some reason, like (Uncaught SyntaxError: Cannot use import statement outside a module (at workspace:52:9))
and with type="module" it is
(Uncaught TypeError: Failed to resolve module specifier "blockly". Relative references must start with either "/", "./", or "../".)
and when it is with those dots and stuff, its 404 not found,
can someone help me? :c

Maribeth Moffatt

unread,
Mar 22, 2024, 4:50:02 PM3/22/24
to Blockly
Hello,

The error message is correct. You cannot use 'import' statements inside a bare <script> tag. For some background information, you might want to read this MDN article about modules in JavaScript.

When writing a JavaScript-based application, you have a lot options on how to structure your code. You might be using modules, which allow you to use `import` statements. Since Blockly itself isn't yet published as an esmodule, if you go this route, you have to use a build system that can convert your code and its dependencies into non-module code. For example, the sample application uses webpack to build the entire application. In its files, you'll see `import * as Blockly from 'blockly/core'` just like the code you're trying to use.

If you're not using modules, then you can't use `import` statements (as the error message says). If you just want to write all of your JavaScript code inside a <script> tag in an html document, then you can't use modules. You will have to load Blockly a different way. One easy way is to use unpkg as described here. In addition to loading Blockly from unpkg, you can also load plugins from unpkg. For example, <script src="https://unpkg.com/@blockly/theme-dark"> will load the dark theme plugin's code. After the plugin has been loaded, Blockly will know how to use a theme called 'dark' and you can set this in the inject options with `theme: 'dark'`.

I hope that helps!

Best,
Maribeth

PilotTim136

unread,
Mar 22, 2024, 5:19:34 PM3/22/24
to Blockly
oh, so last time i tried using upnkg for plugins, it didnt work, thats why i wanted to try nodeJS with blockly (it was php on that) so i could just use unpkg for everything? like every plugin or something like that? (i love blockly btw)

PilotTim136

unread,
Mar 22, 2024, 5:34:52 PM3/22/24
to Blockly
so, news.
The unpkg doesnt really work, it sends a status code of 302: Found and redirects the script to "browse/@blockly/...", wich is a problem, because it doesnt get the script

Maribeth Moffatt

unread,
Mar 22, 2024, 6:34:57 PM3/22/24
to Blockly
Sorry, I'm not sure what you mean. Can you add more details about what the problem is?

You can definitely use Blockly with npm. But if you want to use modules, you'll need to use a build system because Blockly isn't currently published as a module. That's fine and a very popular approach to using the library. You can check out the sample app I linked previously as an example. I am not sure what you mean by using PHP though. Blockly is a JavaScript library so if you want to use it, you'll have to write JavaScript.

Or on the other hand, unpkg should also work for the core library and for all of the plugins as far as I know.

Can you explain why unpkg isn't working for you? I have tested importing the dark theme into a page with unpkg and it's working fine. Yes, there may be a redirect because unpkg will redirect to the latest version, but that shouldn't affect the browser's ability to load the code. Showing your code and any error messages would be very helpful.

Best,
Maribeth

PilotTim136

unread,
Mar 22, 2024, 6:38:57 PM3/22/24
to Blockly
so, i have found out i can use any plugin i want with no problem. but dark-mode is the only thing, that will not want to load properly. either it gives me an 302, and doesnt work, or it doesnt even appear in the networking tab.

Maribeth Moffatt

unread,
Mar 22, 2024, 6:42:24 PM3/22/24
to Blockly
Can you please share the code you're using? Without that, I'm unable to help you debug.

Best,
Maribeth

PilotTim136

unread,
Mar 23, 2024, 7:55:19 AM3/23/24
to Blockly
sure!

<?php
  if(isset($_GET['theme'])){
    $theme = $_GET['theme'];
  } else {
    $theme = "dark";
  }
 
  if($theme == "light"){
    echo '<link rel="stylesheet" href="css/light.css">';
  } else {
    echo '<link rel="stylesheet" href="css/dark.css">';
  }
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Scratch 4 PHP - EDITOR</title>


  <!-- Extensions -->
</head>
<body>
  <div id="copied">
    <center>
      <div id="copiedbg" hidden>
        Copied to Clipboard
      </div>
    </center>
  </div>

  <!-- Early initialization phase -->
  <script src="js/copy.js"></script>
     
  <div id="buttonContainer">
    <button onclick="copy()">Copy</button>
    <button onclick="saveToFile()">Save</button>
    <button onclick="loadFromFile()">Load</button>
    <a href="<domain>"><button>Home</button></a>
    <a href="?theme=<?php if($theme == "light"){ echo "dark"; }else{ echo "light"; } ?>">
      <button>Change theme to <?php if($theme == "light"){ echo "dark"; }else{ echo "light"; } ?> mode</button>
    </a>

    <label style="color: red; font-family: sans-serif;">PHP doesn't work with iframe;
    expect broken results. (works on localhost/webservers that support php as expected)</label>
  </div>

  <div id="blocklyContainer">
    <div id="blocklyDiv"></div>
    <div id="generatedCodeContainer">
    <iframe id="generatedHTMLFrame"></iframe>
      <code><p id="generatedCodeBlockly">...</p>
    </div>
  </div>

  <div id="blocklyworkspace">
    <div id="toolbx">
      <?php include "workspace.xml" ?>
      <button id="extentions" onclick="showExtensions()">EXTENSIONS [BETA]</button>
      <button id="lextention" onclick="loadext()">Load extension via Link</button>
    </div>
  </div>
 
  <!-- Late initialization phase -->
  <script src="blockscomp.js"></script>
  <script src="js/script.js"></script>
  <script src="js/start.js"></script>
</body>
</html>


So, that is the code, and everything works, but the dark-mode doesn't

var workspace = Blockly.inject('blocklyDiv', {
  /*plugins: {
      toolbox: ContinuousToolbox,
      flyoutsVerticalToolbox: ContinuousFlyout,
      metricsManager: ContinuousMetrics,
    },*/
  toolbox: document.getElementById('toolbox'),
  grid: {
    spacing: 20,
    length: 3,
    colour: '#ccc',
    snap: false,
  },
  trashcan: true,
  renderer: 'Zelos',
  theme: 'darkTheme',
  sounds: true,
  zoom: {
    controls: true,
    wheel: true,
    startScale: 0.8,
    maxScale: 15,
    minScale: 0.5,
    scaleSpeed: 1.2,
    pinch: true
  },
});

const backpack = new Backpack(workspace);
backpack.init();

const options = {
    contextMenu: true,
    shortcut: true,
  };
 
  // Initialize plugin.
  const plugin = new CrossTabCopyPaste();
  plugin.init(options, () => {
    console.log('Use this error callback to handle TypeError while pasting');
  });
 
  // optional: Remove the duplication command from Blockly's context menu.
  Blockly.ContextMenuRegistry.registry.unregister('blockDuplicate');
 
  // optional: You can change the position of the menu added to the context menu.
  Blockly.ContextMenuRegistry.registry.getItem('blockCopyToStorage').weight = 2;
  Blockly.ContextMenuRegistry.registry.getItem(
    'blockPasteFromStorage',
).weight = 3;


workspace.addChangeListener(updateCode);

// Function to update the code
function updateCode() {
  var code = Blockly.JavaScript.workspaceToCode(workspace);
  Blockly.JavaScript.addReservedWords('code');
  document.getElementById('generatedCodeBlockly').textContent = code;
  updateHTML(code); // Update HTML in iframe
}

// Function to update HTML content in iframe
function updateHTML(html) {
  var iframe = document.getElementById('generatedHTMLFrame');
  var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
  iframeDocument.open();
  iframeDocument.write(html);
  iframeDocument.close();
}

// Initial code update
updateCode();





So, but if i remove the string from 'theme', the whole workspace just dissapears. 

Maribeth Moffatt

unread,
Mar 24, 2024, 10:18:29 PM3/24/24
to Blockly
I can't test the PHP parts of your code, but the import string you have looks fine. In the inject options, you need: `theme: 'dark'` not 'darkTheme'. 'darkTheme' is not the name of any theme in blockly so this string will not have the effect you're looking for.

> if i remove the string from 'theme', the whole workspace just dissapears. 

I'm not sure what you mean by this. If you remove which string? Is there an error in the console when this happens?

Best,
Maribeth

PilotTim136

unread,
Mar 25, 2024, 2:01:25 PM3/25/24
to Blockly
so, thank you for your help, but a friend of mine got it to work too! thank you so much tho
Reply all
Reply to author
Forward
0 new messages