I'm trying to use Rollup with Babel's external-helpers
. It works, but it's dropping a bunch of babel helpers which I don't even need, for example asyncGenerator.
The docs show a whitelist option but I can't get it to work
rollup.rollup({
entry: 'src/buttonDropdown.es6',
plugins: [
babel({
presets: ['react', ['es2015', { modules: false }], 'stage-2'],
plugins: [['external-helpers', { whitelist: ['asyncGenerator'] }]]
})
]
})
The above has no effect: all Babel helpers are still dropped into my resulting bundle.
What is the correct way of using this feature, and is there a full list of which helpers' names the whitelist array takes?
Or is there some other Rollup plugin I should be using with Rollup to automatically "tree shake" the babel external helpers.
As I have found in this particular issue in the GitHub page.
The Babel member Hzoo suggests that
Right now the intention of the preset is to allow people to use it without customization - if you want to modify it then you'll have to just define plugins yourself or make your own preset.
But still if you want to exclude a specific plugin from the default preset then here are some steps. As suggested by Krucher you can create a fork to the undesirable plugin in the following way
First one is by forking technique
"babel": {
"presets": [
"es2015"
],
"disablePlugins": [
"babel-plugin-transform-es2015-modules-commonjs"
]
}
But if two or more people want to include the es2015-with-commonjs then it would be a problem.For that you have to define your own preset
or extend
the preset of that module.
The second method would involve the tree-shaking as shown in this article done by Dr. Axel Rauschmayer.
According to the article webpack2
is used with the Babel6
.
This helps in removal of the unwanted imports that might have been used anywhere in the project in two ways
single bundle file
. In that file, exports that were not imported anywhere are not exported, anymore.minified
, while eliminating dead code
. Therefore, entities that are neither exported nor used inside their modules do not appear in the minified bundle. Without the first step, dead code elimination would never remove exports (registering an export keeps it alive).Other details can be found in the article.
Simple implemetation is referred as here.
Creating aplugin and greating your own preset can be implemented according to the documentation here
Also as an extra tip you should also use babel-plugin-transforn-runtime
If any of your modules have an external dependancy,the bundle
as a whole will have the same external dependancy
whether or not you actually used it which may have some side-effects
.
There are also a lot of issues with tree shaking of rollup.js as seen in this article
Also as shown in the presets documentation
Enabled by default
These plugins have no effect anymore, as a newer babylon version enabled them by default
- async-functions (since babylon 6.9.1)
- exponentiation-operator (since babylon 6.9.1)
- trailing-function-commas (since babylon 6.9.1)**
Also the concept of whitelisting and blacklisting the plugins has benn brilliantly explained by loganfsmyth here in this thread.
you can pass a whitelist option to specify specific transformations to run, or a blacklist to specific transformations to disable.
You cannot blacklist specific plugins, but you may list only the plugins you want, excluding the ones you do not wish to run.
Update :
According to this article here is an important update -
"The
--external-helpers
option is now a plugin. To avoid repeated inclusion of Babel’s helper functions, you’ll now need to install and apply the babel-plugin-transform-runtime package, and then require the babel-runtime package within your code (yes, even if you’re using the polyfill)."
Hope this may solve your problem
Hope it may help you.
The babel-plugin-external-helpers
plugin is not responsible for injecting those dependencies in the final bundle.
The only thing it controls is that how the generated code will access those functions. For example:
classCallCheck(this, Foo);
// or
babelHelpers.classCallCheck(this, Foo);
It is needed so all rollup-plugin-babel
needs to do is to inject babelHelpers
in every module.
The documentation is misleading, the whitelist
options is not on the external-helpers
plugin. It's on the completely separate module and command line tool called babel-external-helpers
, which is actually responsible for generating babelHelpers
.
It's rollup-plugin-babel
what is injecting babelHelpers
. And does it using a trick to modularize the final code. It calls babel-external-helpers
to generate the helpers, and ignores the whitelist parameter. See my issue requesting to expose an option.
This approach is correct, because rollup will tree-shake the unused helper functions. However some of the helpers (like asyncGenerator
) are written in a way that is hard to detect if the initialization has any side effects, thus preventing removal during tree-shaking.
I forked rollup-plugin-babel
and created a PR which exposes the whitelist option of building babelHelpers in the plugin's options. It can be used this way:
require("rollup").rollup({
entry: "./src/main.js",
plugins: [
require("rollup-plugin-babel")({
"presets": [["es2015", { "modules": false }]],
"plugins": ["external-helpers"],
"externalHelpersWhitelist": ['classCallCheck', 'inherits', 'possibleConstructorReturn']
})
]
}).then(bundle => {
var result = bundle.generate({
format: 'iife'
});
require("fs").writeFileSync("./dist/bundle.js", result.code);
}).then(null, err => console.error(err));
Note that I didn't publish distribution version on npm, you will have to clone the git repo and build it using rollup -c
.
In my opinion the right solution would be to somehow detect or tell rollup that those exports are pure, so can be removed by tree shaking. I will start a discussion about it on github after doing some research.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With