Open dev-ardi opened 2 years 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:
Even something seemingly benign like accepting a new type of value in an API can cause breakage for someone when upgrading: https://github.com/davipon/esbuild-plugin-pino/issues/65. So this is an incompatible API change, which requires a major version bump under semver.
Fixing a minification bug can change behavior: https://github.com/evanw/esbuild/issues/2361. This is not backwards compatible because it could result in a behavior change in bundled code that has come to rely on the old, buggy behavior. So this also requires a major version bump for safety.
When I released support for Yarn Plug'n'Play, I needed to follow that up with some bug fixes. One such fix changed how paths were interpreted, which could cause a different file to be imported when a file has the same name as the enclosing directory: https://github.com/evanw/esbuild/issues/2455. The feature had just been released and was still pretty broken, so realistically no one was using it enough to be broken by this obscure bug fix. However, this bug fix is not backwards compatible because it could hypothetically result in a behavior change in bundled code, so this would have required a major version bump for safety.
I recently added names
to the source maps that esbuild generates: https://github.com/evanw/esbuild/issues/1296. Doing this could hypothetically change the behavior of tools that process esbuild's source maps, so this would necessitate a major version bump under semver.
There are many of these examples...
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.
I'm generally fine with the 0.x. I know exactly where I stand.
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.
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
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).
@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.
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?