Core-js: Reduce minimalistic bundles size

Created on 1 Apr 2018  路  13Comments  路  Source: zloirock/core-js

I've made a custom build with the following code:

require ( 'core-js-builder' )({
  modules: ['es6.array.fill']
})

And the resulting build is 5.5kb, that seems excessively large to me.

Isn't there a way to make it smaller?

I would be surprised if a minified polyfill for this required more than 0.2kb, core-js' file is about 30 times larger than that.

enhancement

All 13 comments

The main problems here: it's maximally strict, it should work everywhere and it contains common export logic. Because it should work everywhere, it should internally implement all of the required logic. The serious part of this logic - ES5 polyfills required for IE8-, for example, Object.defineProperty for method definition or Object.create(null) which required for adding Array.prototype[@@unscopables] object which should contain this method, etc.

Here 3 options how to rework core-js for making minimal bundles smaller:

  • Drop ES3 engines support. Definitely not soon.
  • Loading of required logic to core-js only with related polyfills, so if you don't import 'es6.object.define-property' and some other modules directly, 'es6.array.fill' will not work in IE8-. At this moment, it's not acceptable.
  • Untangle core-js modules, minimize required dependencies. Feel free to add a PR.

Thanks for the explanation.

What about adding a targets option to core-js-builder, 脿 la babel-preset-env, so that by doing this:

require ( 'core-js-builder' )({
  modules: ['es6.array.fill'],
  targets: {
    browsers: ['last 2 versions']
  }
});

the builder can automatically avoid to bundle those polyfills for legacy browsers?

Sounds good, but it's too hard. Anyway, need to think about it.

I've tried to blacklist es6.object.define-property manually with:

blacklist: ['es6.object.define-property']

but it didn't work, I guess because some other polyfill I'm compiling requires this.

It would be nice if we could enforce this setting, in that case those polyfills that depend on this would just assume it's already available.

@fabiospampinato it will not work this way. Fundamental features implemented internally and entry points like es6.object.define-property is just a facade.

@zloirock Wouldn't be better separating modules in individual, installable packages such as @core-js/es6-array-fill ? I known that would be a major refactoring, but it could solve most bundle size problems.

@thiagodp it's absolutely not related to this issue and can't help here - for example, es-shims project use what you propose, but susceptible to this problem even more than core-js.

@zloirock The idea adheres to the 3rd option:

Untangle core-js modules, minimize required dependencies.

The involved refactoring would do the job. Separating into individual modules is a way to refactoring them and to pruning unneeded dependencies. Also, people could choose between using specific modules or all of them (i.e., a unified module).

I know that's hard to do now, but the project could benefit from it more than just refactoring the code.

@thiagodp

Separating into individual modules is a way to refactoring them and to pruning unneeded dependencies.

Sorry, but not in this case. Rather here will be a backward effect - I made many experiments with it.

It will be almost a thousand packages - modules and some thousands of packages - entries for different cases.

Who will add hundreds of polyfill packages to package.json manually? How many users understand what should be added? Almost all will add a package with a collection which will contain almost all of them.

So it will increase not only the bundle size for all users - it will increase the node_modules size for a big part of users - each package has an overhead.

Maybe I'll do it in the future, but for other reasons and not soon.

@zloirock Totally agree. I did not know much about the project's specifics. Thanks for sharing.

@thiagodp if you are wondering what this problem looks with the separate packages approach, see https://github.com/es-shims/AggregateError/issues/13

Hey @zloirock !

Just a question for my understanding and I think this relates also to this issue.

I am using @babel/preset-env with useBuiltIns: usage and target: default. The default target also includes IE. So, in my code I am using the Object.assign functionality.

  • When I bundle the files, babel does correctly bundle the Object.assign polyfill, as it is not supported by IE11:
  • I had another look at the bundle and I see Object.keys is also polyfilled, but it is supported by IE11.

Is it caused because core-js does automatically polyfill down to ES3 and Object.assign depends on Object.keys?

Regards,
Matthew 馃槉

@matzeeable it's not related to this issue. Object.keys is polyfilled in IE11 since it's implemented not properly by the latest spec of the language.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RedHatter picture RedHatter  路  5Comments

koenpunt picture koenpunt  路  5Comments

dwiyatci picture dwiyatci  路  4Comments

yusidi picture yusidi  路  3Comments

Sequoia picture Sequoia  路  5Comments