How to make OpenFL and hxElectron work nicely together?

I know it’s possible to simply take the HTML5 export from OpenFL and drop it in the electron starter project, and it will work pretty much seamlessly. However I want to also be able to make IPC calls in order to communicate with Electron’s NodeJS process. This is where I start to run into problems. The very act of including the hxElectron externs into the project.xml causes this error when I build with openfl html5.

C:/HaxeToolkit/haxe/lib/lime/6,1,0/lime/system/System.hx:322: characters 14-46 : Class<lime._backend.native.NativeCFFI> has no field lime_system_get_time

Presumably, this might be because some of the classes have dependencies to NodeJS when OpenFL is targeting the browser? I’m not sure. The same thing happens if I try to include hxnodejs. Regardless, I just want the browser IPC stuff, not the nodejs IPC stuff. But even when I isolate the IpcRenderer.hx extern class into my project, I still run into some errors. Such as this:

characters 2-18 : Accessing this field requires 'electron' to be enabled

Which is strangely a haxe compilation error, even though by runtime “electron” will already be enabled as a container for the entire OpenFL project.

Does anyone know how I might be able to make electron IPC calls from the OpenFL HTML5 target, allowing you to pass javascript data from the OpenFL HTML5 app to the electron process? Thanks.

probably this can help

1 Like

Nevermind, figured it out. If anyone else runs into this problem it’s because the library autogenerates @:require metadata for an electron compiler flag. So you just have to add a haxedefine to your project.xml with the name electron. Still don’t know what the lime error is all about with include the haxelib in my project.xml, but I just included the folder directly into the project.

But more importantly, now I have to run webpack on the openfl generated js file. Does anyone have any experience with this? Every time I’ve tried it’s resulted in an unusable JS fine. Running it through webpack’s UglifyJS to minify it works file on it, but as soon as I import other libs through a basic webpack configuration, it results in a host of issues.

Have you read this: Electron question ?

Would an NPM-based workflow work better for this, or is there something you’d like from our normal build system instead?

Yeah I’ve seen that and with a basic build, just tossing it into an electron starter kit project it works seamlessly. But I want to also include electron IPC calls (using the electron extern) which seems to require a modular build with requirejs.

Importing any extern with a haxe @:jsRequire metadata appears to break the standard Haxe openfl html5 build when I run it through webpack (to go grab all of the requirejs loaded modules and build them into a single js file) and results in a lime.embed error.

However I’ve found out through experimentation that changing the output file to load with window.require('electron') when running the file through electron seems to work without any webpack transpiling. So I guess I need to figure out how to make @:jsRequire output window.require() instead of require()?

But loading JS libraries / haxe externs with requirejs in a standard openfl html5 build is still a problem for anything (other than this special electron case), which I haven’t really found any concrete answers on while searching this forum or google. Using webpack on the output file with require() calls always seems to break it.

The reason I don’t want to use the NPM-based workflow (if you mean using a JS source) yet is that other libraries that are built ontop of OpenFL like HaxeSpine and HaxeFlixel are not ported to the intermediate JavaScript module format using hxgenjs at the moment, and it looks like it would take a bit of leg work for me to do so as I’ve tried just running them through hxgenjs and the result was broken. Although I’m not ruling that out as a possibility, as it looks relatively easy on the surface (looking at the Starling source).

However I’d still like to build to C++ and Android natively, and the reason I’m using electron at the moment is that as you’ve seen in my other post, hxcpp externs don’t appear to support basic C++11 features like template metaprogramming at the moment, so I will have to make C++ bindings through nodejs modules and electron instead. If that is ever sorted out by the hxcpp contributers, I would like the option to compile natively in the future without switching entirely to OpenFL-JS.

You can use the NPM-based workflow with Haxe code, and do not have to use CommonJS modules for anything beyond OpenFL. OpenFL itself would work as CommonJS modules, and importing it adds @:jsRequire and is compatible with Webpack.

I believe using Haxe, HaxeSpine and other Haxe-based libraries should still be possible. We exported Actuate out to NPM as well so we could include it in our ES5/ES6/TypeScript samples, but if you don’t need anything but Haxe, a standard Haxe library should still work?

We may be able to also look at better integration or support of Electron in the Haxelib-based workflow as well.

1 Like

Okay, I just used Haxe + Haxelib successfully with the NPM-based approach. Here’s how I did it:

mkdir HaxelibTest
cd HaxelibTest
yo openfl

Select “Haxe” from the language drop-down.

In order to use the included copy of Haxelib, you have to remove the local Haxe 3.4.4 and change it to Haxe 3.2.1. With some work, the “NPM Haxe” project should be able to work for 3.4.4 or newer as well, but I guess that isn’t fully working (at time of writing here). I edited “package.json” and changed “haxe” to “3.2.1”, removed “node_modules/haxe” (or you could remove the whole directory) and run npm install in the project directory again. While you have “package.json” open, you can also add another script:

"postinstall": "haxelib --always install build.hxml",

This will run haxelib install for any referenced -lib values in your “build.hxml” when you run npm install. For my test, I added -lib actuate to my “build.hxml”, and ran npm install again.

Here was my quick sample code:

import openfl.display.Sprite;
import openfl.display.Stage;
import motion.easing.Linear;
import motion.Actuate;

class App extends Sprite {
	public function new () {
		super ();
		var sprite = new Sprite (); (0xFF0000); (0, 0, 100, 100);
		addChild (sprite);
		Actuate.tween (sprite, 10, { x: 100 }).ease (Linear.easeNone);
	static function main () {
		var stage = new Stage (550, 400, 0xFFFFFF, App);
		js.Browser.document.body.appendChild (stage.element);

npm start -s and it was working properly.

If you do not want (or need) to use a local copy of Haxe, you can npm uninstall --save-dev haxe on your project (and remove the “config” for it if you prefer) and use -lib in your build.hxml just the same. You’ll install and manage haxelib globally, like normal. Either way, I have Webpack + OpenFL + regular Haxe libraries working. The important caveat is that this approach is OpenFL without any Lime APIs, which some libraries may use

1 Like

Thanks Joshua! With a bit of tinkering, it worked. :smiley:

(author of linked repo here)
I’m sure it could be helpful as an example of an electron app built using Haxe, but neither OpenFL or Lime are used in that project.
Sorry :man_shrugging: