vitejs / vite

Next generation frontend tooling. It's fast!
http://vitejs.dev
MIT License
67.45k stars 6.07k forks source link

[docs] Default production target is confusing #13556

Open nulladdict opened 1 year ago

nulladdict commented 1 year ago

Documentation is

Explain in Detail

Hi! Default browser compatibility for production seems to be outdated or confusing.

The text says that it's "support for es modules, dynamic import and import.meta", however chrome version seems to be too high (so are others, chrome is just an example). According to caniuse, minimal chrome version that supports all of this features is chrome 64 (^1, ^2, ^3).

I believe the confusion comes from https://github.com/vitejs/vite/pull/2976. And chrome 87 was chosen arbitrary as it was what browserslist said at the time.

Today the query returns quite a different result (playground). Note that I'm not including the import.meta since there's no query for that but it shouldn't matter.

So, as a result the docs (and default target) are stuck in a weird place. It's not the minimal viable version neither it is a current recommended version. It's somewhere arbitrary in the middle.

Your Suggestion for Changes

I think the docs should mention both minimal and recommended versions in terms of browserslist queries.

Minimal version is almost the same as the supports es6-module and supports es6-module-dynamic-import, minus a couple of browser versions for import.meta.

Recommended one is kinda weird though, since defaults now almost fully covers everything that vite relies on (playground for browsers that are in defaults, but don't have es modules or dynamic import)

Another question is what to do with default build target. We can leave it the same, since we don't want to break stuff. Or we can bump it to another arbitrary value, but it would get outdated right away. Imo the solution is to resolve defaults to esbuild targets, but it's outside of the scope of this issue.

Reproduction

No response

Steps to reproduce

No response

bluwy commented 1 year ago

I've seen this confusion now and then, but the versions we used are intentionally not following the minimum versions matching the feature set. We'll bump the versions on majors as needed based on browser usage, or specific feature needs. For example, we had to bump Safari to v14 so that esbuild can support BigInt, but it isn't something we should document since it is a side effect.

Maybe we can clarify that the versions we chose reflect popular browser usage, and not the minimum versions.

nulladdict commented 1 year ago

For me the source of confusion was that the feature set didn't match the description. Moreover, the es2015 was also strange to see, since as far as I understand this wouldn't actually work in browsers without the legacy plugin

I have no trouble with saying "hey, by default we support this popular versions (updated every major release), but you can comfortably go lower to this versions or higher to match usage in the wild"

Ayushjha132 commented 1 year ago

@nulladdict I am going to fix this doc confusion. Please!! guide me.

nulladdict commented 1 year ago

Not sure if I have enough context for this, but here's my understanding (for apps, no idea about libs).

Since vite outputs <script type="module"> you can't get lower than supports es6-module without using the plugin-legacy. Most real world apps would probably use dynamic imports, so the next tier is supports es6-module and supports es6-module-dynamic-import.

If you want to go more modern than the current default targets one place to start is browserslist's defaults and supports es6-module and supports es6-module-dynamic-import. You'll probably want to adjust the query according to your needs and your region. Also esbuild doesn't understand this syntax, but there's a plugin for that. More info here: https://github.com/vitejs/vite/issues/11489

Now the most tricky part. There's a number of syntax features that esbuild cannot lower to a particular target environment. So if your app uses any of them you'll get a build error and you will probably have to raise your targets (or something might be not supported yet or at all). Some notable examples of features that require a higher targets are import.meta, BigInt, top-level-await, and import-assertions.

I don't know if there's an exhaustive list anywhere, but the code for downleveling js features lives here: js_parser_lower.go and required target versions can be found here: js_table.go. Also I'm not sure if documenting esbuild internals is a useful thing for most of the users.

Edit: after reading a bit, it looks like new using syntax is already supported and one more unsupported feature is ArbitraryModuleNamespaceNames

nickserv commented 1 year ago

What if Vite used the defaults Browserslist query for consistency with other tools, but also pinned the dependency so the team can manage breaking changes to browser support manually? This should ideally be done in a major release to reduce impact of breaking changes.

Rationale

As @nulladdict mentioned in playground for browsers that are in defaults, but don't have es modules or dynamic import, the difference in users is minimal (currently 1.1% globally and 0.18% in the US). Additionally, only Opera Mini and KaiOS users would be affected. Both of these browsers are primarily useful in markets with budget phones, which are more likely to not have touch or JavaScript support, and may require the legacy plugin for better support.

nulladdict commented 1 year ago

As far as I know esbuild doesn't support opera mini target, so browserslist-to-esbuild plugin just ignores it^1. As a result defaults currently translates to esbuild's 'chrome109', 'edge112', 'firefox102', 'ios15.6', 'safari15.6'

I feel like it's a decent recommendation and covers everything that esbuild cannot downlevel. It updates automatically, so vite wouldn't need to keep track of changes unless we get some new compatibility issues with esbuild.