-
Notifications
You must be signed in to change notification settings - Fork 361
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"zero configuration" - but not respecting most package.json
options?
#938
Comments
I'd argue that requiring an specific
That's configuration to me, if that's what you expect. But people have different expectations, nothing wrong with that. While I do agree with that sentiment, I could also see how that could be frustrating if you needed to configure both your Microbundle build script AND your
You might not have read the docs thoroughly enough. Modern mode is mapped to The
Did you copy/paste the wrong snippet here? No
No, it's not: Lines 271 to 277 in fb0a437
I'm guessing you didn't include Our docs have a config for you to copy/paste. If you skip over that and aren't super familiar with Node's rules, you could run into issues. I'm not sure how we can address that better, certainly open to suggestions. That being said, I do currently have a few issues with Microbundle's current name resolution setup (see #896) but that's not related to this. There are some rough spots, no doubt, but this seems to just be an issue of missing important steps in the docs.
Hm, I believe it should output a main/entry .d.ts matching the name you provide. Will look into this, thanks.
The plethora of other .d.ts is due to TSC, I believe. We use I believe I remember Jason putting together a setup to bundle them all together for some project, will have to look into that again. I think we all agree it's not ideal, though, for the moment anyways, it shouldn't cause any functional issues.
Yep, it's on the roadmap to (one day, hopefully) complete: https://github.com/developit/microbundle#-roadmap
We really appreciate you writing this up! I think there's a couple issues you ran into that need to be fixed on your end in your config, but there's certainly a wealth of feedback here for things we can look into doing better in the future. Sorry you ran into difficulties with this.
I suppose that just depends on what you call "extra". Microbundle outputs a set of sensible defaults, but I guess we differ from whether you'd call a The |
Looked into the We cannot even rename the corresponding entry You can use |
Hmm, well, there is this package, which appears to do it via the Typescript API? https://www.npmjs.com/package/rollup-plugin-dts
Right. Square peg in a round hole. It's the story of Javascript isn't it. 🙄 |
Interesting, hadn't heard of that one.
That project is using TS's API to read and write files, which is a bit different from using TS to compile (and what I was referring to). Not entirely sure how using TS differs from just using Node to read and write honestly, but regardless, that plugin is a post-TS compilation step to combine Theoretically we might be able to add it on top, will need to look into it. Maybe due to using the TS API it can pick up on the TS transpilation plugin writing directly to the filesystem.
Yeah. Rollup and |
Honestly though, the biggest issue with microbundle for me right now is the configuration. I mean, yeah, if you copy/paste the example from the README, you happen to get something that works - but as soon as you change anything (even the package name) everything goes wrong. Returning to this:
Having thought about this, I don't agree. The configuration in To reverse the question: when would you want configuration that doesn't match your Is there any useful case for deliberately configuring microbundle to produce something that can't be reached or isn't declared or defined in the package metadata?
Having to configure twice (first in Why wouldn't you use the information that is inevitably there anyhow? If it's not "zero configuration", then at least it's "sensible defaults", derived from things you need to specify anyhow. Why not? 🙂 |
No, if you copy/paste the example in the README you get the product of many hours of our time spent in the rabbit hole of creating output that is usable in every major bundler and Node. It's not pure chance, it's the result of a bit of rather esoteric knowledge on the subject that most people don't have or need. That's totally fine, and is why we provide an example over expecting everyone to be able to make their own. I really don't understand this criticism, especially after running into the above error. It should be clear our examples don't just "happen" to work.
As soon as you change names (or extensions) you're expected to understand Node's package resolution mechanism, yes. We're certainly open to suggestions on how to provide a better experience, but if you ignore our recommended setup, and write an invalid one yourself? It's a bit out of our hands.
Let's say we did match your That's not to say we can't provide warnings, but a potential issue is that package exports are a fairly complex system, and we cannot necessarily assume Microbundle is in control of the whole process. Preact, for example. actually has a post-build script to make duplicate copies of a bundle but change the file extension. Ejecting from Microbundle is a fairly common need for a whole plethora of reasons. Providing a bunch of warnings might not be ideal as they could decrease the signal-to-noise ratio. This is something I'll look into more heavily in the next few days/weeks, however. We certainly want to improve Microbundle where we can.
You're making the assumption that every consumer of Microbundle's output does so via packages where a
No, it's native to Node. There are many ways to consume JS outside of Node.
It, for the most part, already is. You ran into issues providing invalid specifications and skipping the docs (ignoring the TS thing, as unfortunately we just can't control that bit, though I'd like to). |
Sorry, Ryan - I think I'm not explaining myself well. 😕 All I meant to point out with this, is that there's no link between the information you put in I think that's a problem. That's been my only point from the start.
Okay, so some people publish packages that aren't even valid npm packages. I didn't know that. But I'm not trying to suggest you shouldn't be able to override the defaults - if somebody wants to use npm to publish things that aren't even installable packages, then so be it. All I'm suggesting is maybe those aren't safe, helpful, meaningful defaults - I still don't understand why you wouldn't derive meaningful defaults from If I'm wrong about that, there's something very fundamental I'm not grasping here.
I didn't skip the docs, I just read it with a different set of assumptions. I understand now what's actually in I'm sorry, and maybe I'm an idiot, but I'm still not grasping why you couldn't use You're not configuring everything twice, unless you want to diverge from the defaults. Am I making any sense here? If I'm completely wasting your time here, I really do apologize. Feel free to ignore me. I'll admit, the whole node/JS/TS ecosystem is baffling, confusing and completely overwhelming to me. No matter how many articles, tools, courses and tutorials I plow through, I only seem to get more confused and overwhelmed. (If you can point me to anything that's going to help me make sense of all this craziness, please share. I'm more than willing to learn. I too have spent "many hours in the rabbit hole", but the tunnels seem to go in circles and the exits never seem to lead where I wanted to go. 😅) |
There is a link, but it's probably just not as "hard" of a link as you might like. The default is just setup so that keys your provide rename the default formats when applicable. I do agree with you that a better default would be in fact to only output formats where matching keys are found, but that was set way before I knew the tool existed and I think it's unlikely that the behavior can really change now as it's matured. Thinking about just the first-party usage alone, there'd probably be a fair bit of breakage/issues upon changing the defaults, much less for the wider community. I'll certainly keep that in mind, maybe we can change that, but I think for now it's a bit unlikely, unfortunately.
I'm a bit confused by this. Getting both configurations exactly right (matching output format to
Microbundle doesn't set any expectations about what your This is an issue but the other way around, in that if you configure Microbundle, you need to make sure your But if you deviate the keys in your
Well, the thing is that your criticism technically is a safe default. If you specify a Again, I do agree, this isn't ideal, and I'd never (knowingly) publish a package with a bunch of unused files, but.... that's not necessarily uncommon in the ecosystem and it wouldn't be an "issue" per se. Sometimes this can even be intended, though I too would much prefer users passing the There's also times where we do need to ignore and not match what's in the
I was referring to the mistaken mapping of The It's tough. This stuff (
Not sure what you mean here. You are able to specify where to generate the outputs[1] when you provide valid entries.
I think this is just going to be an issue of some disagreement over what counts as "configuration". I'd say adding keys to your Microbundle itself is "zero configuration" in the sense that you just run it and you have working output you can run with. The specific environment that you're targeting may require some config on top, but not necessarily. I have used
I mean.. that's kind of what's done now. You specify keys you want in order to get a working package and you don't have to pass any flags to Microbundle. You'll get some extra output, but if you're using this with NPM, that's not necessarily a problem. Node and any bundler won't use files unless you provide paths to them in your
Gosh, certainly don't apologize for something like this. No need, and I'm filling up a notebook of changes to consider lol.
I think I've lost a non-insignificant % of my life dealing with this sort of thing... kinda horrifying to think about 😅. It's confusing and overwhelming as there's a lot of ad-hoc standards and individual projects running with a config/implementation that's specific to them. I've spent a fair bit of time on build tooling and libraries, and there's always some other tool that doesn't respect a standard you'd think is universal. It's a swell time /s.
Best resource that I know for some of the community-driven specs and their implementations is probably Webpack's package exports docs which covers a bunch of different fields, sub-fields, expected formats, and what tools support it. It's a real mix-n-match of horror, though getting better. It's a ton of very specific information though, so might be overkill to do anything more than skim. You probably don't need to know which tools support which subset of the Node on the other hand is much simpler: their docs on [1]: there are some limitations there, like the TS entry name you ran into, as well as some issues where file paths aren't fully resolved from what's listed in the `package.json`. This is generally only an issue if you're trying to output different formats in different directories, though this will actually be supported when #896 is merged. |
Sure, but I don't think
To my understanding, that's just "default configuration". I mean, sure, that could mean you have no configuration, if the default configuration happens to match your expectations and your So look. I decided to give Parcel 2.0 a shot, and this is what I thought "zero configuration" meant: {
"name": "inertion",
"source": "src/index.ts",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"engines": {
"node": ">= 16"
},
"scripts": {
...
"build": "parcel build"
},
...
} It's using The targets page of Parcel's docs explains for every setting how, why and whether a default is established based on your This is what I thought "zero configuration" meant - it's "plug and play" with the project configuration you should/already have, with the option to override. That's quite different from just having some defaults for every option, I think.
Very cool. I'm glad you're not taking this the wrong way. 😄 |
The "zero configuration" portion is entirely separate from this issue is my point. You can run into it anywhere.
Different interpretations is all. That's what this project is running with as "zero configuration"; you need not provide any config in order to get a tiny module built that works in a number of environments. |
As to the meaning of "zero configuration", from my small sample size of 16 respondents, it's a tie. 🙂 https://twitter.com/mindplaydk/status/1510515106999898115 It seems the original meaning of the term "zero configuration" was in regards to networking - where you just connect to a network, and the computer auto-configures your IP and DNS etc. based on external factors. So in it's original sense, I think the term "zero configuration" does imply "plug and play", meaning something auto-configures based on what's already there - in that sense, I think Parcel (which, to my knowledge, popularized the use of the term with regards to bundlers) got it right. Either way, I would love it if Microbundle did more of that. 🙂 |
Your timelines are off, just to be clear, though I'm really done talking about different interpretations of "zero configuration". That's not the definition in use here and you'll just have to accept that. Microbundle was released and using "zero configuration" in it's ReadMe for 6 months before the first Parcel version was released. Nothing against Parcel, they can use whatever language they'd like, but continuing to hold it up as the de facto standard when it's much newer (it was one of the very last tools to the bundler party) is an odd choice. |
I may be completely ignorant of something, so forgive me, but isn't "zero configuration" meant to imply that your
package.json
gets treated as the "source of truth"?Meaning, the intent is for
package.json
to govern what gets generated, filenames, and so forth - directly ensuring that the default settings match what yourpackage.json
specifies?Because it seems like
microbundle
more or less completely ignores mypackage.json
, and I have to manually configure everything anyway?For example, I tried this first:
Which resulted in builds for every format supported - I had to add the
--format modern
switch to disable the other formats.By adding
module
and specifying a path, haven't I explicitly said "this is the only kind of format I need"?It also does not seem to respect the path. The output filename is
lol.modern.js
, despite my specifyingmodule
as./dist/lol.js
, and you end up with a package that can't be installed at all.I decided to try
exports
withdefault
instead:This similarly gets ignored - it doesn't use the filename, and it doesn't govern what gets generated; the filename, apparently, is always derived from
name
and the paths you specify are ignored.(and yes, I noticed the
--name
switch, where I could explicitly specify this again - but having to configure the same thing first for npm and then for microbundle, doesn't that kind of clash with the idea of "zero configuration"?)Likewise, this being a Typescript project, I tried adding
types
:This gets even more confusing, as the presence of
types
does have an effect - it does trigger the creation of.d.ts
files. However, the value appears to be ignored - the.d.ts
files just get filenames derived from the input filenames. (It also does not emit a single.d.ts
file, as I had hoped - but that's probably an unrelated issue or a non-feature.)Things got more curious still, when I attempted multiple entry-points:
As I expected at this point, this had no effect, and
reporting.js
just wasn't generated - however, when I addedsrc/index.ts src/reporting.ts
to themicrobundle
command, not only did it generate both files, but in addition, suddenly the filenames inexports
were being applied:(Side note: the contents of the output
dist/wat.js
file somehow magically is what I expected - it's not clear to me how microbundle gets fromsrc/index.ts src/wat.ts
back to either the./wat
name or the./dist/wat.js
path in theexports
section and figures this out? Other than the wordwat
, there's no direct relationship between either the name or the path and the input file - I wasn't expecting this to work, I was just sort of trying things and got lucky...)Thinking I had figured out the special sauce (explicitly specifying the entry file) I reverted back to this:
Solved, right? 😅
Wrong.
Apparently, specifying the filenames in
exports
only works when you specify more than one entry point.I wanted to share this whole user journey to give you some idea of what the developer experience might be like for some people. I'm sure there's some way to find a "winning configuration", but after sinking another half-day into this, I'm just going to go back to rollup... again.
It's not the first time I've attempted to use microbundle - and please don't get me wrong, I don't mean any disrespect, and I see this working for a bunch of projects.
But as compilers/bundlers go, this is not the most intuitive or pleasant experience. The idea of "zero configuration" appeals to me, but I can't honestly say that this delivers.
I guess maybe it depends on what you expect or mean by "zero configuration"? Personally, I take that to mean "zero extra configuration" - as it's obviously not possible to do anything without some sort of configuration, somewhere. I thought the idea was you derive a sensible default configuration from what's there anyway, your
package.json
file, and perhaps with the option to override?Maybe that's not it at all, but I got the impression from other tools that that's the idea?
Are my expectations way off track here?? 😄
The text was updated successfully, but these errors were encountered: