{"action":"created","issue":{"url":"https://api.github.com/repos/webpack/webpack/issues/6023","repository_url":"https://api.github.com/repos/webpack/webpack","labels_url":"https://api.github.com/repos/webpack/webpack/issues/6023/labels{/name}","comments_url":"https://api.github.com/repos/webpack/webpack/issues/6023/comments","events_url":"https://api.github.com/repos/webpack/webpack/issues/6023/events","html_url":"https://github.com/webpack/webpack/issues/6023","id":277056551,"number":6023,"title":"Allow webpack to be lazily loaded in order to support polyfills using feature detection","user":{"login":"rosenfeld","id":32246,"avatar_url":"https://avatars1.githubusercontent.com/u/32246?v=4","gravatar_id":"","url":"https://api.github.com/users/rosenfeld","html_url":"https://github.com/rosenfeld","followers_url":"https://api.github.com/users/rosenfeld/followers","following_url":"https://api.github.com/users/rosenfeld/following{/other_user}","gists_url":"https://api.github.com/users/rosenfeld/gists{/gist_id}","starred_url":"https://api.github.com/users/rosenfeld/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rosenfeld/subscriptions","organizations_url":"https://api.github.com/users/rosenfeld/orgs","repos_url":"https://api.github.com/users/rosenfeld/repos","events_url":"https://api.github.com/users/rosenfeld/events{/privacy}","received_events_url":"https://api.github.com/users/rosenfeld/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2017-11-27T15:24:31Z","updated_at":"2017-11-30T11:04:44Z","closed_at":"2017-11-30T11:04:44Z","author_association":"NONE","body":"**Do you want to request a *feature* or report a *bug*?** Feature\r\n\r\n**What is the current behavior?**\r\n\r\nWebpack provides no way to use feature detection to load polyfills required by the bundle or Webpack itself.\r\n\r\n**If this is a feature request, what is motivation or use case for changing the behavior?**\r\n\r\nCurrently, webpack requires the presence of window.Promise, for example. That means, a webpack bundle will not work in IE11, for instance, unless we add a polyfill before the webpack bundle. However, adding a polyfill for all browsers is not good, as we add a new request and more bytes do download and parse which is a waste for browsers already supporting Promise (all modern browsers).\r\n\r\n[This article](https://philipwalton.com/articles/loading-polyfills-only-when-needed/) already discusses the problem in depth, but I'm happy to discuss the alternatives in the comments if you will.\r\n\r\nIt would be awesome if webpack allowed us to delay its execution somehow. For example, we could add a script tag with \"window.webpackDelay = true\" before loading webpack bundles. Then we'd be able to either load webpack through \"window.loadWebpackBundles()\" (provided by Webpack) if no polyfills are required or we could call it once the polyfills are applied to support the missing features. This is also basically what that article suggests as the best approach, but unfortunately it isn't supported by Webpack out-of-the-box, while I think it's a good idea to support it in webpack core and to make it easy.\r\n\r\nRight now, I'm using the following work-around, which is not possible for all sorts of bundle configurations. I've followed the steps in the [Caching guide](https://webpack.js.org/guides/caching/). That splits the bundle in 3 sources: the webpack runtime, vendors and the application itself. Currently, just requiring the runtime won't cause Promise to be immediately used, so it's safe to load it in IE11 for example. The runtime also defines the webpackJsonp function. Then I have the opportunity to load the runtime script, add my custom script to handle feature detection based polyfills, and finally add the other 2 source scripts.\r\n\r\nThe custom script will take care of storing the original webpackJsonp function and it will override with a simple function that will simply store the arguments in an array. Then, the script can use feature detection to decide when to actually call the original webpackJsonp function with those arguments once all required features are loaded.\r\n\r\nHow do you feel about allowing us to have greater control on when the webpack code should be run in order to allow us to add the missing polyfills for older browsers?"},"comment":{"url":"https://api.github.com/repos/webpack/webpack/issues/comments/348156502","html_url":"https://github.com/webpack/webpack/issues/6023#issuecomment-348156502","issue_url":"https://api.github.com/repos/webpack/webpack/issues/6023","id":348156502,"user":{"login":"rosenfeld","id":32246,"avatar_url":"https://avatars1.githubusercontent.com/u/32246?v=4","gravatar_id":"","url":"https://api.github.com/users/rosenfeld","html_url":"https://github.com/rosenfeld","followers_url":"https://api.github.com/users/rosenfeld/followers","following_url":"https://api.github.com/users/rosenfeld/following{/other_user}","gists_url":"https://api.github.com/users/rosenfeld/gists{/gist_id}","starred_url":"https://api.github.com/users/rosenfeld/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rosenfeld/subscriptions","organizations_url":"https://api.github.com/users/rosenfeld/orgs","repos_url":"https://api.github.com/users/rosenfeld/repos","events_url":"https://api.github.com/users/rosenfeld/events{/privacy}","received_events_url":"https://api.github.com/users/rosenfeld/received_events","type":"User","site_admin":false},"created_at":"2017-11-30T11:04:44Z","updated_at":"2017-11-30T11:04:44Z","author_association":"NONE","body":"Hi @sokra, that makes perfect sense, thanks. I didn't thought of using a wrapper around the entries that would simply include them without running. It's a bit more work, but it certainly works, so I'm closing this issue.\r\n\r\nI'm aware of those trade-offs, but I'm talking about polyfills of old features, such as fetch and Promise, which is basically only missing in one of our supported browsers IE11 and I hope to be able to drop support for IE11 as soon as there are only a few people using it.\r\n\r\nHaving said that, I'm okay with degrading the performance of old browsers because if users of old browsers cared about performance they would be using newer browsers in the first place. I just don't want to degrate the performance in newer browsers just because we're supporting older ones.\r\n\r\nAnyway, old browser users would only have their performance degraded once as most likely the polyfills will be already cached permanently and it's very unlikely that we would ever change that polyfill.\r\n\r\nI've also thought about your other idea, which would currently work fine since there would be a bundle for IE11 and another bundle for the other browsers, however, thinking about the long term, the approach I suggested is more flexible in case we start using other modern features which could be lacking in other browsers in the future. This is how it could work making it easy on the my side, while requiring an extra round-trip in older browsers:\r\n\r\n``` html\r\n<script>\r\nconst missingFeatures = [];\r\nif (!window.Promise) missingFeatures.push('Promise');\r\nif (!window.fetch) missingFeatures.push('fetch');\r\n// ...\r\nif (missingFeatures.length === 0) { loadApp(); return; }\r\nconst polyfillsUrl = 'https://cdn.polyfill.io/v2/polyfill.min.js?features=' +  missingFeatures.join(',');\r\nconst script = document.createElement('script');\r\nscript.onload = loadApp;\r\nscript.src = polyfillsUrl;\r\ndocument.head.append(script);\r\n</script>\r\n```\r\nThis way only the missing features would be loaded in older browsers. If we replace the above with an anonymous function with var instead of const it could even work in IE9 and IE10. Or we could process it with webpack and babel and load this script as an external source. For browsers supporting HTTP2 the extra resource won't mean an extra round-trip. The only extra round-trip would happen for older browsers through the cdn.polyfill.io domain and in most cases they would get an empty 304 response most of the time, although the round-trip won't be avoided. If we really want to improve the performance in older browsers, then we could serve those polyfills from our own domain. If we only care about browsers supporting HTTP2, we could even serve those polyfills separately. Or we could join all polyfills in a single request and degrate the performance of less older browsers by making them require all polyfills from supported browsers even if they would support 90% of them natively. It's a trade-off based decision. Particularly I'm fine using the trick above for now. Specially because right now only IE11 would be affected and if someone is using IE11 it's clear to me that they don't care about performance at all.\r\n\r\nThanks for the suggesting of using require.include as a wrapper around vendor dependencies that would use some missing feature in modern browsers. That gives me much more flexibility, thanks!"}}
{"actor":{"display_login":"rosenfeld"}}