Having the Extern blues again :(

Hi people :). For more than 5 years I’ve been toiling away at a rather massive Haxe project, which I intended and still intend to be a pretty major release for the ecosystem. It’s still under wraps however, until I clarify some patent concerns. Anyway, suffice to say I poured a lot into it.

I’m relying on externs to accomplish some of the things I’m doing, because I’m transpiling to NodeJS. Until now, I’ve been using @haxiomic 's excellent dts2hx library for adding new libraries when I needed them. But now I’m having some weird issue with it not generating externs for a very simple library I created.

This is the library. The only thing I’m interested in exporting from it is the SReader.readCharacters function:

It’s meant to also contain a service, but that’s not relevant for the export. For now, I just want to export a single function from the thing, and I have trouble on both tracks:

First, dts2hx doesn’t seem to work properly for it. I install it locally using npm pack and npm install shardyard in another project, but then when I run npx dts2hx shardyard, dts2hx complains that it can’t find the module. For whatever weird reason, it tries to find shardyard in the root of node_modules. Have absolutely zero clue why it does that.

So then I tried to create externs manually. I made this class:

@:jsRequire("shardyard/dist/SReader") @valueModuleOnly extern class SReader
{
	static function readCharacters (): Array<NCharacter>;
}

@:jsRequire("shardyard/dist/vo/NCharacter") @valueModuleOnly extern class NCharacter
{
	public var name: String;
}

And I use it like so:

logger.debug(SReader.readCharacters());

Which compiles fine. But when it runs, I get:

node:internal/modules/cjs/loader:1544
      throw err;
      ^

Error [ERR_REQUIRE_ESM]: require() of ES Module my_project_path\node_modules\shardyard\dist\SReader.js from my_project_path\export\main.js not supported.
Instead change the require of SReader.js in my_project_path\export\main.js to a dynamic import() which is available in all CommonJS modules.

What’s that whole thing with dynamic import() ?

And can anybody help me use dts2hx? I would very much prefer that it works, because it makes it much easier to generate externs and keep them updated.

This error means that the code generated by Haxe is using require() to try to load an ECMAScript module. However, require() is meant to be used with CommonJS modules only.

Your shardyard project seems to be configured to generate ES modules from TypeScript. I suspect that you may want it to generate CommonJS modules from TypeScript instead. This would require some kind of tweak to your tsconfig.json file.

Alternatively, you could try to find an alternate way for Haxe to import ES modules correctly (without require()). The thing is… I don’t think that Haxe natively supports ES modules. However, I found this library, which may help you use ES modules instead of CommonJS modules, if you prefer: GitHub - back2dos/jsImport: import ES6 modules into Haxe generated JavaScript

Try "types": "dist/Shardyard.d.ts" or "types": "dist/SReader.d.ts" in your package.json

Though you’ll probably want an index.d.ts that exports everything you want to export instead

For require, indeed it would be nice to generate js.import instead, related issue

There is a macro to get it working in the meantime

I’m not sure when it’ll land in haxe, for js builds I’d consider it high priority since you can’t use modern libraries (like three.js)

2 Likes

@haxiomic You are absolutely awesome :brown_heart: :smiley: . I probably said something along those lines before. I fixed the package.json and moved some stuff in an index.d.ts and lo and behold, it WORKS! Oh, and I had to change my TS project to use CommonJS modules…

You are totally right that the Haxe team should give some love to the JS target and implement support for more modern JS. But what kills me the most with Haxe is the debugging & refactoring support in IDEs, which is far behind TypeScript as it stands. I should probably open an official issue in the Haxe project for that, because the authors of the VS Code extension mentioned that they are limited by the somethingsomething in Haxe :smiley:

Anyway, I’m always so impressed by this community. Even though we are at least 1000 times smaller than TypeScript, stuff still gets sorted out… somehow. I feel I get so much support from people here and I’m super grateful for that! And I will give something in return… soon :slight_smile:

4 Likes