ImportScripts order of import

For some reason, SugarCube executes my importScript back-to-front then front-to-back:


:: StoryScript [script]
console.log("StoryScript started");
  [..., "js/game/references.js", ...]

:: StoryInit
/* Used to set up all SugarCube-dependants*/
console.log("StoryInit started");
window.c.alias.setup(Engine, State);


console.log("Init"); = || {}

js/game/references.js: = || {}
console.log("References"); = {};

Browser console log:

References               VM2298:62
Init                     VM2298:196
StoryScript started      VM2298:303
StoryInit started        VM2299:2
Init                     init.js:12
References               references.js:2

The @importScripts documentation in SugarCube2 states that js files defined not within the same array are loaded sequentially. Yet I’ve seen upon multiple refreshes that the order of print does not change at all, meaning the order is probably deterministic. What am I doing wrong?

note: the importScripts() function call in your example is missing a semi-colon from the end of it.

Where Is the js folder located in relation to the ‘root’ folder containing the files whose contents you want embedded inside the generated Story HTML file?

eg. Does your project folder & file structure look something like…


…where adventure.html is the Story HTML file generate from a command like…

tweego src -o adventure.html

…and the src folder is the “root” of all the content that that generated HTML file contains.

Or is that structure more like this…


…where a command like…

tweego . -o adventure.html

…was used to generate the Story HTML file.

Because if it’s more like the 2nd structure then the contents of the js files were embedded inside the Story HTML file’s <script role="script" id="twine-user-script" type="text/twine-javascript"> element, along with the contents of the StoryScript Passage.

Which would result in the contents of those js files being executed twice: first when the contents of the above mentioned <script> element is processed by the engine; and again when the importScripts() function call does its thing.

And that could potentially result in a Console log like you’re seeing.

I created a test project using a folder & file structure like the 1st example I gave, and the Console contained only…

StoryScript started
StoryInit started

Perfect, that worked. Thank you Greyelf!

First, because I’m curious. If you’re using Tweego, which can bundle your JavaScript files into the compiled HTML file, why are you attempting to use importScripts()? That’s typically something you only need to use when you’re loading something from an external site—e.g., a CDN—or when using Twine 2 and you don’t want to copy-paste everything into its singular JavaScript section.


I’m thinking there’s a “not” in there that shouldn’t be or you’re a bit confused.

To be clear. Loose URLs and array groups are imported concurrently, while URLs within an array group are imported sequentially relative to each another.

For example, showing both loose URLs and an array group:

// Import a.js, b.js, and the c.js/d.js group concurrently,
// while importing c.js and d.js sequentially relative to
// each other.
1 Like

Thank you TheMadExile! I don’t know how many times I’ve read that code block and understood it the opposite!

As for the use of importScripts(), what do you recommend? What’s the standard way? Just have the js folder inside the twee folder? But that would make the scripts import back-to-front?

I’d have Tweego compile your JavaScript files into the HTML file, yes. As to their order, you can control that in various ways.

  1. Name them, and their subdirectories, such that your filesystem puts them into the order you need.
  2. Specify them on the command line in the correct order. Files listed on the command line are processed in exactly the given order.
  3. Use an external bundler—e.g., Rollup—to combine your files into the correct load order, then have Tweego compile that bundled file. Pro: This allows you to use an ES module style workflow with your JavaScript. Con: This does require additional tools and setup and may not be worth it for small amounts of JavaScript.
1 Like