- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 7.4k
Description
Description
Currently there are two main ways of adding polyfills to modern builds. Using an external polyfill service or using plugin-legacy with modern options. In this issues I want to focus on the plugin-legacy experience
If users want to only add polyfills to modern build they need to do one of:
- Declare them upfront using modernPolyfills: string[]which feels somewhat pointless because they can just import the modules directly in the main entrypoint instead and skip the plugin altogether
- Use auto-detection with modernPolyfills: true, modernTargets: string | string[]which will auto-detect used features and inject polyfills
Auto detection relies on babel (through babel-plugin-polyfill-corejs3 and  babel-plugin-polyfill-regenerator) which leads to a couple of consequences
First, plugin needs to transform all chunks using babel. babel is slower than swc but since it transforms built chunks (as far as I understand) it shouldn't be a big issue
Second, the syntax for targets in esbuild and babel is very different. esbuild (and vite) currently do not support browserslist while babel does. This leads to a bit of a confusion
esbuild and browserslist are not entirely compatible. There's browserslist-to-esbuild library that can convert from browserslists targets to esbuild. The conversion is lossy and discards anything that isn't supported by esbuild (e.g. samsung internet)
Before #20393 users had to set both build.target and modernTargets and were fully in control of what gets built with what target
After the PR users now have to unset build.target and set modernTargets which will transform browserslist query and set the esbuild target. This feels somewhat backwards (why does a plugin control the target and not the other way around?) and in rare cases can change the output (if the targets were sufficiently different)
Suggested solution
The ideal solution is for oxc, rolldown and then vite to support functionality that plugin-env provides. This way users can use oxc-based polyfill detection and entirely avoid plugin-legacy for modern build
As far as I could see, there's scaffolding for this in oxc but the functionality is not implemented yet and I have to idea if it's on the roadmap
Other solution is to teach plugin-legacy to use build.target as modernTargets which is more intuitive but requires syntax conversion. I'm not entirely sure it's possible since esbuild supports targets such as es2020 and browserslist doesn't. I'll investigate and post results in comments
Alternative
Do nothing and accept the current state. Maybe add a bit more clarity to plugin-legacy docs
Docs for modernTargets currently say:
- the option will override build.target
- if the option is not set it will fallback to the default value
- the option should not be set if the plugin renders legacy chunks
To me a couple of questions arise:
- if I don't set the option would build.targetstill be replaced by some default?- won't build.targetfallback to its default value?
 
- won't 
- if I want to both render legacy chunks and add modern polyfills what do I do?
Additional context
No response
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.