hygen icon indicating copy to clipboard operation
hygen copied to clipboard

Add ESM support to JS files

Open stevefan1999-personal opened this issue 5 years ago • 12 comments

So that we no longer has to write cancerous module.exports!!

stevefan1999-personal avatar Jan 02 '19 12:01 stevefan1999-personal

Well I do know export default doesn't corresponds to module.exports...and it seems like simply adding the wrapper of ESM on top of hygen main file wouldn't work (see here)...

stevefan1999-personal avatar Jan 02 '19 12:01 stevefan1999-personal

Hi Steve This specific piece of code was written to allow requiring on demand because it made hygen faster when you don’t need that functionality. Completely open to moving to ESM if it can support dynamic require. Any thoughts?

jondot avatar Jan 02 '19 16:01 jondot

The problem is export default means module.exports.default in CJS, and merely await import would not account for that. I'm hacking to figure it out

stevefan1999-personal avatar Jan 03 '19 09:01 stevefan1999-personal

Thanks, please let me know if you've come to a conclusion and we can take it from there.

jondot avatar Jan 05 '19 10:01 jondot

@jondot we can build two files and define in package.json entries for module and main. Ofc, first file in cjs format and second in es module format.

epszaw avatar Jan 08 '19 17:01 epszaw

not sure, but i think question was originally about a specific code point in prompt.js (as opposed to embeddability of Hygen -- in which case, definitely can add different module system build if needed)

jondot avatar Jan 08 '19 17:01 jondot

I like the idea. And it seems it shouldn't be difficult to do.

The good news is that hygen and e.g. its config-resolver already uses promises to load files. It might be as easy as changing a single line. prompt.js seems to be loaded via function returning promise as well.

However, it might be a BREAKING CHANGE. In package.json , I don't see the engine specified. The import() has been available since Node@12. Another great news is that in a few weeks (April 2021), Node@12 will be the oldest supported LTS version available - so no serious harm shell be done :)

Another, more decent (not breaking) option could be to provide another bin executable, e.g. hygenes, that would support the ESM files. And hygen cli can stay unchanged. Not sure right now, how to handle prompt.js though. I suppose it will be not that complicated...

What do you think?

stropho avatar Mar 10 '21 19:03 stropho

A nice stopgap would be allowing a .hygen.cjs config file so that I can still use "type": "module" in my project with esmodules.

That way, I can make a project today with modern esm support, but still use hygen. When hygen adds esm support, I can drop the cjs extension for js and refactor a bit.

jlarmstrongiv avatar Jun 21 '22 12:06 jlarmstrongiv

Any word on this? I'd love to use "type": "module" in my project...

jacobjove avatar Oct 16 '22 15:10 jacobjove

A nice stopgap would be allowing a .hygen.cjs config file so that I can still use "type": "module" in my project with esmodules.

That way, I can make a project today with modern esm support, but still use hygen. When hygen adds esm support, I can drop the cjs extension for js and refactor a bit.

yeah, would be grat to support and allow .cjs config file in the meantime :)

marckraw avatar Oct 17 '22 13:10 marckraw

For the workaround, to be able to use config object i did this thing: image

So it,s basically, .hygen folder, with fake package.json file with only information that it will use commonjs, and then the script in my main package.json, who will run hygen command from inside this .hygen folder

Convoluted but works :D

marckraw avatar Oct 17 '22 13:10 marckraw

I was looking at it.

Now that current supported node versions allow to dynamically import esm modules is feasible to implement it

There must be some kind of typescript support since currently it converts dynamic import to require:

From

const configResolver = new ConfigResolver('.hygen.js', {
  exists: fs.exists,
  load: async (f) => await import(f),
  none: (_) => ({}),
})

To

const configResolver = new config_1.ConfigResolver('.hygen.js', {
    exists: fs_extra_1.default.exists,
    load: (f) => __awaiter(void 0, void 0, void 0, function* () { return yield Promise.resolve().then(() => __importStar(require(f))); }),
    none: (_) => ({}),
});

blikblum avatar May 26 '23 11:05 blikblum