tunnckoCore / parse-function

(!! moved to tunnckoCore/opensource multi-package repository !!) :trident: Parse a function into an object using espree, acorn or babylon parsers. Extensible through Smart Plugins.
https://tunnckocore.com/opensource
MIT License
37 stars 6 forks source link

module and main entry points are not exporting the same API #161

Open ericmorand opened 5 years ago

ericmorand commented 5 years ago

See those two issues:

https://github.com/ericmorand/twing/issues/284

https://github.com/webpack/webpack/issues/8171

To summarize, in the current state, dist/index.es.js and dist/index.js are not exporting the same API. It means that what works when using parse-function in a node env is not guaranteed to work when using parse-function in the browser after parse-function has been bundled by WebPack or Rollup.

tunnckoCore commented 5 years ago

Strange... it's export default.. I will check it later today

tunnckoCore commented 5 years ago

Those are the configs for Rollup.. https://github.com/tunnckoCoreLabs/hela-config-tunnckocore/tree/v0.5.19/config

It creates ...

Minute later: I think I got what's the problem. parse-function does not have pkg.legacy and pkg.unpkg fields which are needed for the legacy-browsers and modern-browsers configs. Hm.

GitHub
tunnckoCoreLabs/hela-config-tunnckocore
A `hela` shareable config (preset of tasks) for @tunnckoCore GitHub organization - tunnckoCoreLabs/hela-config-tunnckocore
tunnckoCore commented 5 years ago

In anyway... i will release #138 in day or two, for sure. So everything will be simplified in terms of usage and dev workflow / building.

tunnckoCore commented 5 years ago

Can you give me what's the difference between them? What's exported by both?

ericmorand commented 5 years ago

require('parse-function/dist/index.js'); returns the parse function itself. require('parse-function/dist/index.es.js'); returns an object with a default property.

It means that you can't use require('parse-function) in your code because it will resolve to the function itself when run on the server and to an object with a default key on the browser.

ericmorand commented 5 years ago

For what it's worth, here is how I export my modules to provide the same API for both:

index.cjs.js:

class Foo {
}
exports.Foo= Foo;

index.es.js:

export class Foo {
}

Then, using either const {Foo} = require('index.cjs.js'); or const {Foo} = require('index.es.js'); leads to the same result: Foowill contain the class/constructor.

tunnckoCore commented 5 years ago

Consistency is good thing, yea. But it's totally normal to expect require-ing esm to return an object with default key property.

That's why it's in the module field. Because bundlers will load the module field instead, and so the behaving is the same.

example.js

import parse from 'parse-function'

console.log(parse)

is the function if you use bundlers or running it with node -r esm example.js.

require-ing ESM inside CJS is what happening to do the inconsistencies. And that's hat i didn't liked in Babel 6. They kinda forced users to do require('foo-bar').default because they stopped appending module.exports but only doing them as exports.[name]

tunnckoCore commented 4 years ago

Next version should fix this once and forever.