Skip to content

Fix modular builds.#2035

Open
player-03 wants to merge 16 commits intoopenfl:8.4.0-devfrom
player-03:lime-modular
Open

Fix modular builds.#2035
player-03 wants to merge 16 commits intoopenfl:8.4.0-devfrom
player-03:lime-modular

Conversation

@player-03
Copy link
Contributor

@player-03 player-03 commented Mar 3, 2026

As discovered by @Digivorix, building with -D lime-modular is currently broken, and likely has been for 7+ years. This mode outputs separate .js files for Haxe, Lime, and OpenFL, among others, with the idea that most of them can be reused. Each file would add their classes to $hx_exports, then the final app could reference those exported classes.

The core of the problem is that, instead of passing $hx_exports to the app, we created an empty object and passed that instead. Without access to basic OpenFL, Lime, or Haxe classes, the app couldn't run.

As far as I can tell, the only reason not to pass $hx_exports is because System will overwrite $hx_exports.lime.embed. We want to expose output.js's wrapper function in that spot, and the wrapper needs to call the function System exports. Solution: have System export to $hx_exports.lime.system.System.embed instead.

Downside: if the wrapper never runs, then the page can't call lime.embed, which it might expect to be able to do. But that would require running haxe Export/html5/haxe/release.hxml manually to remove the wrapper, which also strips away the embedded libraries, so I don't think that's ever been a supported use case.

Note: this PR is not enough to run OpenFL apps in modular mode. OpenFL will need a patch of its own.

Note 2: this includes #2013, because I considered a solution that would have required it.

player-03 and others added 13 commits January 1, 2026 22:38
The lime module source is now located in src/lime instead of in the root directory.
Update the backend package path found in the source tags that get used in modular build mode.
The haxelib classpaths added to the hxml string in ModuleHelper.hx did not take any custom classpaths defined in a library's haxelib.json file into account.

This change relies on the new getPathClassPath function added to my fork of the hxp library. It can be found in the classpath-change branch.
Haxe 4 removed the XMLSocket class from the js package, so it will only be included in modular builds if the app is being built with Haxe 3.
Html5 dependencies will still be embedded like before on non-modular builds.
--no-inline is now deprecated, so it will only be used if someone is building with Haxe 3.
Three layers of nesting is too many, adding confusion for minimal benefit.

Additionally, there's no need to calculate and pass `$globals`, when Haxe already runs the exact same calculation.
This mode failed because we weren't passing `$hx_exports` into `script()`. In this mode, Lime's core classes are stored in `$hx_exports.lime`, so we need access.

The reason we didn't pass `$hx_exports` is because `System` writes to `$hx_exports.lime.embed`. We do want to get access to that function, but don't want it to be overwritten. Therefore, we passed in an empty object, and read `lime.embed` from that object.

The most straightforward solution is to store the two different functions in two different places. That way, there's no risk of one overwriting the other. Nor can the function accidentally call itself, so we don't have to check for that either.
This must have been missed in bc3a5f7.
Didn't mean to commit these, whoops!
The flag is `lime_modular` now, so this would only have run if `modular` was defined for some other reason. If it did run, the only difference would have been that it wouldn't quite allocate enough space.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants