parcel: Parcel does not include polyfill for older browsers even when `browserslist` is declared in the `package.json`
🐛 bug report
RT.
🎛 Configuration (.babelrc, package.json, cli command)
Reproduction: https://github.com/SukkaW/parcel-issue-7419/
🤔 Expected Behavior
Parcel should include corresponding polyfills for cutting edge JavaScript features (like WeakMap, Set and Object.fromEntries) from core-js, which is a dependency of @parcel/config-defaults.
😯 Current Behavior
Parcel doesn’t include any polyfill at all, even though browserslist is declared in the package.json.
💁 Possible Solution
Really? swc already handle this correctly. You guys just don’t use coreJs and mode: usage option by default? And you are telling me the parcel can be used with zero-configuration?
💻 Code Sample
https://github.com/SukkaW/parcel-issue-7419/
🌍 Your Environment
| Software | Version(s) |
|---|---|
| Parcel | 2.0.1 |
| Node | Node 17.2.0 |
| npm/Yarn | 8.1.3 |
| Operating System | macOS 12.0.1 |
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 6
- Comments: 21 (12 by maintainers)
So what is the current recommended solution here?
@devongovett @mischnic, any updates on this? Maybe you should fix documentation (at least add link to this issue)
https://parceljs.org/languages/javascript/#browser-compatibility
It doesn’t working as expected, misleading and people waste time trying to setup parcel to work correctly
what’s the best workaround for this? back to having babel but running parcel to pickup a
babel.config.json? This does work but wonder what is working for othersMaybe it has improved, but I don’t believe it is possible for
mode: 'usage'to be fully accurate without a type checker. For example, core-js includes polyfills for builtin methods likeString.prototype.includes. In order to detect when to include this, they’d need to look for any call of any method namedincludeson any object. Without type information, it’s not possible to know whether the target is a string or not. This leads to including way too many polyfills, bloating the bundle. In addition, there are ways of accessing methods that are not statically analyzable, leading to polyfills not being included. Therefore, I’m not sure usage detection is a very good idea.I think it’s better to manually include polyfills either by importing
core-jsand letting Parcel/SWC include all polyfills needed for your environment, or just including the ones you need. The latter will result in the smallest bundle size.Just a sidenote, but I think Parcel docs are at least a little bit misleading when it says this (in the Browser compatibility section):
Compare with Vite docs (also the Browser compatibility section) where you can find the info about polyfills straightaway:
Of course Parcel docs talk about transpilation only, but I’m not sure if many people make that connection.
@devongovett
I have just updated the issue title to
Parcel does not include polyfills for older browsers. The title should be accurate now.Also FYI, the swc has evolved and the
mode: usagedetection is now accurate (Shout out to @Austaras. He has fixed this in swc 1.2.220).@mischnic The swc has evolved and the detection is now accurate (since 1.2.220). Does the parcel team have a plan to adopt it (and solve the issue)?
@avalanche1 As far as I can tell, this is actually working mostly as expected. The core-js modules that are included is based on what is in your
package.json:browserslistvalue. If you set it tochrome 99then the included polyfills will be substantially less. In my case, the resulting bundle was51.81 KBwith--no-optimize --no-scope-hoist. If I change thebrowserslistto beIE 6, then the resulting bundle is654.59 KB. Quite a big difference.Interestingly, in my opinion 51 KB is quite big for targeting only Chrome 99. Upon investigation, it appears that
swcisn’t quite smart enough to remove polyfills that are depended on by core-js itself. For example, Chrome 99 includes theweb.immediatemodule, when in turn requiresobject-get-own-property-descriptordespite not actually needing it in chrome 99.This is the require hierarchy:
Though, since these are
internalsand notmodules, maybe there’s a specific reason they aren’t removed. Regardless, I don’t think this is such a big deal since when you optimize the build, the file size is significantly smaller at10.21 KBfor Chrome 99, and111.44 KBfor IE 6.