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 namedincludes
on 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-js
and 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: usage
detection 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:browserslist
value. If you set it tochrome 99
then the included polyfills will be substantially less. In my case, the resulting bundle was51.81 KB
with--no-optimize --no-scope-hoist
. If I change thebrowserslist
to 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
swc
isn’t quite smart enough to remove polyfills that are depended on by core-js itself. For example, Chrome 99 includes theweb.immediate
module, when in turn requiresobject-get-own-property-descriptor
despite not actually needing it in chrome 99.This is the require hierarchy:
Though, since these are
internals
and 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 KB
for Chrome 99, and111.44 KB
for IE 6.