benmerckx / genes

Generates split ES6 modules and Typescript definitions from Haxe modules.
44 stars 8 forks source link

How to require module-level functions? #9

Closed kevinresol closed 4 years ago

kevinresol commented 4 years ago

In ES it is written as:

import { extend } from 'react-three-fiber'
extend();

In Haxe:

@:jsRequire('react-three-fiber')
extern class Utils { // just a dummy class name
    static function extend():Void;
}

Haxe-generated js (works):

var Utils = require('react-three-fiber');
Utils.extend();

but genes generates (doesn't work):

import Utils from 'react-three-fiber'
Utils.extend();

which is then translated by webpack into:

react_three_fiber__WEBPACK_IMPORTED_MODULE_2__["default"].extend()

Note the default field access is invalid because the original export is not default:

export function extend() {}
kevinresol commented 4 years ago

Webpack actually emits a warning:

560:0-5 "export 'default' (imported as 'Utils') was not found in 'react-three-fiber'

benmerckx commented 4 years ago

We could generate this?

import * as Utils from 'react-three-fiber'

But then I wouldn't be quite sure how to require default. Would that be @:jsRequire('package', 'default') only?

benmerckx commented 4 years ago

Gave the above a go. It fails this test: https://github.com/benmerckx/genes/blob/20f8b140847a2e94dc1efd2e840abdd5fb89e96b/tests/TestRequire.hx#L3

When imported as import * as Assert from "assert" it fail with 'Assert is not a function'.

Because of @:selfCall here it actually requires a default import: https://github.com/HaxeFoundation/hxnodejs/blob/1201320d159a583e613d3076eb00850ffeac57ca/src/js/node/Assert.hx#L56

And I realize there's more than a few instances where a default require is expected: https://grep.app/search?q=%40%3AjsRequire%5C%28%5B%5E%5C%2C%29%5D%2A%5C%29&regexp=true

I'm thinking of either processing the class and checking if it only has statics or providing some custom metadata to generate asterisk imports.

kevinresol commented 4 years ago

@:genes.wildcardImport?

kevinresol commented 4 years ago

Meta is easier for the macro.

Processing the class would be easier for user. I guess the requirements are as follow (any more?)

  1. @:jsRequire has only one argument
  2. class contains only statics
  3. no @:selfCall
kevinresol commented 4 years ago

How about implementing the metadata solution first so that I can continue testing on my codebase?

benmerckx commented 4 years ago

Yeah, I'll try it this week

benmerckx commented 4 years ago

I tried the "check for only statics" way.