Closed donmccurdy closed 2 years ago
Webpack (unfortunately) treats .js
and .mjs
ESM differently.
A way to opt-out of the .mjs renaming might be a solution for me
This is done with Webpack treats "type": "module"
..mjs
the same as "type": "module"
.
I would recommend against pointing "module"
at the modern
output, and certainly would recommend against it using .mjs
. Use the esm
output with .js
instead.
This is done with "type": "module".
This results in microbundle renaming my main
entry to .cjs
, and unfortunately seems to break the test suite, for weird reasons, on another package I have consuming the original package. That is not microbundle's fault, the test suite (tape) does not do so well with ESM, and I may need to replace it anyway, but this is not an easy switch at the moment.
I hadn't realized microbundle was writing modern output to .mjs files and transpiled output to .js files in this update — why that distinction?
This results in microbundle renaming my main entry to
.cjs
Well, that's just how dual output works w/ Node semantics. .js
& .mjs
or .cjs
& .js
. As Node prioritizes "exports"
over "main"
, I suppose you might be able to rename your main entry to .js
, though I wouldn't really recommend that.
Altering package exports is (usually) a task for a semver major -- reverting & waiting might be a better option.
I hadn't realized microbundle was writing modern output to .mjs files and transpiled output to .js files in this update — why that distinction?
Not sure I follow. What distinction? The linked PR just brings Node extension semantics to Microbundle's esm
and modern
outputs.
Not sure I follow. What distinction?
Sorry, to clarify — I thought that esm
and modern
were both ES Modules, just with the latter using modern EcmaScript features. If both are modules, why is only one written with an .mjs
extension?
I would recommend against pointing "module" at the modern output, and certainly would recommend against it using .mjs. Use the esm output with .js instead.
I can't support as many old browsers and node.js versions as the microbundle defaults include, it is not so simple as just transpiling. But using browserslist
to force ES2017+ on the esm
output might work here? I'll try that. Thank you!
Sorry, to clarify — I thought that
esm
andmodern
were both ES Modules, just with the latter using modern EcmaScript features. If both are modules, why is only one written with an.mjs
extension?
That's correct, however, Node extension semantics only applies to modules you wish to load in Node.
Node doesn't consume "module"
. That was a community driven spec to allow bundlers to make use of ESM long before Node supported it well. This means that the file that "module"
points to doesn't necessarily need to play by Node's rules.
I can't support as many old bundlers and node.js versions as the microbundle defaults include, it is not so simple as just transpiling. But using
browserslist
to force ES2017+ on theesm
output might work here? I'll try that. Thank you!
If you're just targeting ES2017, feel free to keep using modern
.
Keep in mind that Microbundle outputs according to what's valid in Node (and therefore the spec going forward). If you don't care about Node, or know your way around these configs, feel free to do some post-build renaming of the output. That's totally valid.
It's impossible to support everything, so Microbundle tries to ensure it's not outputting modules that will crash Node if you try to load them. That seemed like the best default.
Edit: Looking at the attached report, honestly it looks like you should just ditch "exports"
and do the following:
{
"main": "./dist/foo.js",
"module": "./dist/foo.esm.js"
}
Going to close this out, as there's nothing really actionable here for the project. We made this adjustment for correctness, and while it's unfortunate that some tooling has quirks regarding correct usage, the previous output was invalid in Node.
Certainly feel free to respond and I can try to help though.
Things seem to be working now, so for posterity here's where I ended up:
browserslist
to make sure all my builds use ES2017+I should've tried that first when I hit the v0.14 → v0.15 upgrade issues. As described in https://github.com/developit/microbundle/issues/977 I'd hoped to switch several packages to ESM-only, but there are enough pain points in other tools with that (😭) that I think just need to experiment with some of the newer and less stable packages before going further on ESM.
No more questions here, thanks again @rschristian!
Glad to hear it! The working solution, that is.
Hopefully in a couple more years this will get a lot simpler, though, I think some of us have had our fingers crossed for a few years now....
After updating a package from microbundle v0.14 to v0.15, I ended up with the following change in my
package.json
, to account for #950 —Since then I've gotten reports from downstream users that my package no longer works in their Webpack builds, because my package also has a dependency on gl-matrix, which uses multiple entrypoints like
gl-matrix/mat4
andgl-matrix/vec3
extensively:https://github.com/toji/gl-matrix/blob/8962b2e7727594022e59e48e605049c69403da60/package.json#L6-L20
This manifests in end-user projects (which depend directly on my package, and transitively on gl-matrix) with the following error:
Is there a workaround here that doesn't require the end-user to reconfigure Webpack when consuming my package? A way to opt-out of the .mjs renaming might be a solution for me, as using .js extensions hadn't been an issue before.