ShakaCode | ShakaCode Blog | Rails On Maui Blog | Rails | ReactJs | JavaScript | Webpack | Productivity |

Best way to include babel-polyfill?


#1

I’m looking for the best way to handle babel-polyfill with Webpack v2 and a common vendor-bundle.js.

I want to setup a vendor-bundle that is auto computed, per the docs:

  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks(module) {
        // this assumes your vendor imports exist in the node_modules directory
        return module.context && module.context.indexOf('node_modules') !== -1;
      },
    }),
  ],

Previously, in Webpack v1 I manually defined the vendor components.

If I define my entry:

  entry: {
    // This will contain the app entry points defined by
    // webpack.client.rails.hot.config and webpack.client.rails.build.config
    app: [
      'babel-polyfill',
      './app/startup/clientRegistration',
    ],
  },

And I have several entries, I’ll be adding babel-polyfill to each one. Maybe I want to include it in the auto-generated vendor-bundle.

Maybe I can skip listing the entry point of babel-polyfill and instead put this in an import?

And then webpack v2 will magically put babel-polyfill in the vendor-bundle?

Would the same apply for ‘es5-shim’? Is this still needed?


#2

Good Q’s.

Those docs are pretty funny; they start out with the explicit vendor example, where they are manually specifying the modules to put in vendor (in the example, it’s just moment). Then they say, oh, you can do this automatically and they show the code for that. Then they say, but wait that’s stupid because you have a runtime manifest that changes every time and will negate any caching benefit. So, then they go back to the explicit vendor bundle again. So it seems, according to the docs, that you can’t really actually do the implicit vendor bundle, or at least it wouldn’t make sense to.

By the way, Alex, we should look into this runtime manifest bundle thing, I don’t think we’ve actually checked to make sure our vendor bundle’s hash is the same if we haven’t changed dependencies.

Maybe I can skip listing the entry point of babel-polyfill and instead put this in an import?

That would work too, but you’d have to do it in the entry point of every bundle, so I would just opt for the explicit vendor bundle approach and put it in there. I’m not sure how to accomplish this with the implicit/auto-computed approach.

And then webpack v2 will magically put babel-polyfill in the vendor-bundle?

I can’t say for sure, but I would think if you explicitly tell Webpack that you want babel-polyfill in your app bundle’s entry points, then I don’t think it will take it out and put it into vendor. I could be wrong though.

Would the same apply for ‘es5-shim’? Is this still needed?

I can’t remember the reason for the es5-shim. I’m not sure if it’s for browser compatibility or was for fixing execjs problems back when we were still using that for server rendering. We should definitely take another look at this.


#3

@robwise if we’re using the rule for put anything in ‘vendor-bundle’ from node_modules, that should ensure just one copy of babel-polyfill.


#4

Yeah but how does that reconcile with tree shaking? If you’re not making it an entry point and it’s not being imported in your code, then it’s just going to get dropped, right?


#5

This may help a bit.

The goal was to avoid import of babel-polyfill from my source code as well as I was trying to avoid:

  entry: {
    pageA: ['babel-polyfill', './pagea'],
    pageB: ['babel-polyfill', './pageb'],
   ...
  },

Finally I’m using:

  entry: {
    vendor: 'babel-polyfill',
    pageA: './pagea',
    pageB: './pageb',
  },

Not sure it is best solution, but at least best I found. I was also trying to replace babel-polyfill by transform-runtime, but it doesn’t work for me.

Let me note that in both cases the vendor is auto-created by:

new webpack.optimize.CommonsChunkPlugin({
  name: "vendor",
  minChunks: function (module) {
    // all imports from the node_modules directory are bundled into vendor
    return module.context && module.context.indexOf('node_modules') !== -1;
  },
}),