parse-function icon indicating copy to clipboard operation
parse-function copied to clipboard

module and main entry points are not exporting the same API

Open ericmorand opened this issue 6 years ago • 8 comments

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.

ericmorand avatar Oct 17 '18 08:10 ericmorand

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

tunnckoCore avatar Oct 17 '18 09:10 tunnckoCore

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
A `hela` shareable config (preset of tasks) for @tunnckoCore GitHub organization - tunnckoCoreLabs/hela-config-tunnckocore

tunnckoCore avatar Oct 17 '18 10:10 tunnckoCore

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 avatar Oct 17 '18 10:10 tunnckoCore

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

tunnckoCore avatar Oct 17 '18 10:10 tunnckoCore

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 avatar Oct 17 '18 11:10 ericmorand

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: Foo will contain the class/constructor.

ericmorand avatar Oct 17 '18 12:10 ericmorand

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 avatar Oct 17 '18 19:10 tunnckoCore

Next version should fix this once and forever.

tunnckoCore avatar Oct 18 '19 21:10 tunnckoCore