evanw / esbuild

An extremely fast bundler for the web
https://esbuild.github.io/
MIT License
38.1k stars 1.14k forks source link

esbuild should move to version 1.0.0 #2544

Open dev-ardi opened 2 years ago

dev-ardi commented 2 years ago

Based on https://semver.org/#how-do-i-know-when-to-release-100

I feel like the API is stable enough across versions, and it's used in production in a vast number of projects, companies and packages.

As a user of esbuild API I feel like it's important for the version number to comunicate how compatible one version is from the next: Can I safely update my esbuild in my project without having to read all of the patch notes?

evanw commented 1 year ago

Can I safely update my esbuild in my project without having to read all of the patch notes?

First, here's what esbuild currently does:

0.MINOR.PATCH
    │     │
    │     ╰─ Updating is probably safe (outside of some obscure edge cases)
    ╰─ Upgrading is probably not safe (a reasonable number of people may be impacted)

This issue is a request to change things to this instead (which is what semver is):

MAJOR.MINOR.PATCH
  │     │     │
  │     ╰─────┴─ Updating is totally safe
  ╰─ Upgrading could hypothetically not be safe

I've been thinking about this and I'm not sure how I feel about it. I agree that esbuild is used widely in production, and I do make an effort to keep esbuild stable unless a change is necessary. But esbuild is also very complex with a large API surface and many interconnected features, so many changes that I often make to esbuild would require a major version bump for safety under this definition.

Here are some recent examples which I have considered to be patch changes but which would be semver major changes under this definition:

Following "can I safely update esbuild in my project" rigidly basically makes semver meaningless for regularly-updated packages like esbuild, as there would quickly be a major version bump and your question will almost always be irrelevant (you just wouldn't get any updates at all).

One way of looking at this is to say "semver is supposed to be about API changes, so bug fixes that don't change the API are fine even if they could hypothetically break someone." But that doesn't accomplish your goal of "can I safely update esbuild in my project." It has also been clarified that by "API" semver means all behavior, not just the interface: https://github.com/semver/semver/issues/874#issuecomment-1247614295.

Another way of looking at this is to say "if a bug fix realistically isn't going to break 99.9% of people, then it can be a patch." But then that's not semver, which is problematic because npm has set up their ecosystem such that semver is expected. It also relies on opinions and guesses, which goes against the goal of using a version number as a guarantee.

As a user of esbuild API I feel like it's important for the version number to communicate how compatible one version is from the next

Ironically I think this is what makes semver not a good fit for esbuild. I feel that the current versioning approach more effectively communicates how compatible one version is from the next than semver. With the current approach the answers to "can I safely update esbuild in my project" are "probably" or "probably not" but with semver the answers are "definitely" or "perhaps" (with most updates falling under "perhaps"). Semver makes it hard to distinguish widely-compatible from likely-incompatible changes.

TL;DR: With the current versioning scheme, you should pin esbuild to a specific version and not update it unless you need to. If you want to upgrade esbuild to version "0.x.y" to fix a specific bug you're hitting or to get a new feature that you need, you can expect minimal breakage when upgrading if "x" stays the same but you should be aware that things might break when upgrading if "x" changes.

shellscape commented 1 year ago

I'm generally fine with the 0.x. I know exactly where I stand.

manast commented 8 months ago

There are a lot of valid points in this post, although I think it is actually possible to have and eat the cake here, because basically you can just have a versioning system that is close to SemVer in spirit but that fits your particular view of versioning. For instance, major versions increase when the risk of breaking something is pretty high, micro versions increase as today, only for bug fixes, minor for new features with a very high confidence that they would not break anything, otherwise increase major. That would keep most people happy I think, and also would remove that 0 for major which looks a bit useless right now and just seems to signal that this is not a production ready product.

rtritto commented 1 month ago

With major version 0, each library uses a different esbuild version (no deduped dependencies).

➤ YN0000: · Yarn 4.4.1
➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0007: │ esbuild@npm:0.23.1 must be built because it never has been before or the last one failed
➤ YN0007: │ esbuild@npm:0.21.5 must be built because it never has been before or the last one failed
➤ YN0007: │ esbuild@npm:0.19.12 must be built because it never has been before or the last one failed
➤ YN0000: └ Completed
➤ YN0000: ┌ Deduplication step
➤ YN0000: │ No packages can be deduped using the highest strategy
➤ YN0000: └ Completed
➤ YN0000: · Done

If esbuild is stable, it's better to upgrade to v1.

FYI @evanw

jakebailey commented 1 month ago

Bumping to v1 would not help that. v0.22 to v0.23 contained breaking changes, which is how it works for 0.x bumps. Moving to v1 would just mean that the same breaks would cause a bump to v2, causing the same duplication in node_modules (because they are not compatible).

mark-wiemer commented 2 weeks ago

@evanw it's been nearly two years and about 8 bumps (from 0.16.0 to 0.24.0), have you reconsidered this? For me seeing v0 was a bit of a turnoff as I thought this project was still early in development or significantly unstable. It also feels strange not knowing whether a new release includes just bugfixes (v1.0.1) or new features (v1.1.0).

That said, I do think you should stick to semantic versioning regardless, and staying in v0 is OK by me. I've seen enough projects rely on this and looked at the changelog enough to know this is a stable project ready for production use :)

That said, I'm not sure all of the above issues would constitute a SemVer major change. The key is to look at what's in scope for esbuild and what's not. esbuild is designed to build code correctly. It's not designed to build JS files in a certain format, just "whatever works" and is "minified" to the best of its ability.

  1. https://github.com/wd-David/esbuild-plugin-pino/issues/65: This one is confusing, I can't say either way, it may have been a design flaw in the dependency
  2. 2361: Anyone who depends on buggy builds should know that bugfixes may, well, remove the bug. Obviously they may not know whether there's a bug in their built code, but in that case, they should be very very cautious to make any changes to their dependencies. They should know that esbuild's goal is not to provide consistent behavior with previous releases, but correct behavior, removing bugs from previous releases. (Relevant xckd)

  3. 2455: Depending on how thoroughly-tested this was, I'd've considered releasing it under an "experimental" or "unstable" flag. But yes, if it was released under the main API, it would've needed a SemVer major bump

  4. 1296: As long as the default wasn't changed, this could be a simple minor bump. Tools that depend on output would have failed at all the above changes as well, plus those tools should be designed such that they know esbuild may tweak its output at any time. Again, esbuild isn't built to output JS in a certain format, just JS that works. Tools may break, but esbuild doesn't have any contract to support those tools. Users of those tools should know not to upgrade esbuild without checking if the tool remains compatible with it.