Skip to content

Commit f2782aa

Browse files
jeremenichelliskipjack
authored andcommitted
docs(guides): add "polyfills on demand" to shimming (#1528)
Add an explanation of how to load polyfills on demand section in the shimming guide. Resolves #938
1 parent 4d5eb08 commit f2782aa

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

src/content/guides/shimming.md

+85
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ contributors:
55
- pksjce
66
- jhnns
77
- simon04
8+
- jeremenichelli
9+
related:
10+
- title: Reward modern browser users script
11+
url: https://hackernoon.com/10-things-i-learned-making-the-fastest-site-in-the-world-18a0e1cdf4a7#c665
12+
- title: useBuiltIns in babel-preset-env
13+
url: https://github.com/babel/babel-preset-env#usebuiltins
814
---
915

1016
`webpack` as a module bundler can understand modules written as ES2015 modules, CommonJS or AMD. But many times, while using third party libraries, we see that they expect dependencies which are global, AKA `$` for `jquery`. They might also be creating global variables which need to be exported. Here we will see different ways to help webpack understand these __broken modules__.
@@ -158,3 +164,82 @@ module.exports = {
158164
## Node Built-Ins
159165

160166
Node built-ins, like `process`, can be polyfilled right directly from your configuration file without the use of any special loaders or plugins. See the [node configuration page](/configuration/node) for more information and examples.
167+
168+
169+
## Loading polyfills on demand
170+
171+
It's common in web projects to include polyfills in the main bundle. This is not recommended because we are penalizing modern browsers users by making them download a bigger file with unneeded scripts.
172+
173+
The simplest way to mitigate this is by adding a separate entry point in your webpack config file including the polyfills your project needs.
174+
175+
```javascript
176+
// webpack.config.js
177+
module.exports = {
178+
entry: {
179+
polyfills: [
180+
'babel-polyfill',
181+
'whatwg-fetch'
182+
],
183+
main: './src/index.js'
184+
}
185+
// ... rest of your webpack config
186+
};
187+
```
188+
189+
An alternative is to create a new entry file and manually import these packages.
190+
191+
```javascript
192+
// src/polyfills.js
193+
import 'babel-polyfill';
194+
import 'whatwg-fetch';
195+
```
196+
197+
```javascript
198+
// webpack.config.js
199+
module.exports = {
200+
entry: {
201+
polyfills: './src/polyfills.js',
202+
main: './src/index.js'
203+
}
204+
// rest of your webpack config
205+
};
206+
```
207+
208+
In your html file you need to conditionally load the `polyfills.js` file before your bundle. How you make this decision depends on the technologies and browsers you need to support.
209+
210+
```html
211+
<script>
212+
var modernBrowser = (
213+
'fetch' in window &&
214+
'assign' in Object
215+
);
216+
217+
var scripts = [ '/main.js' ];
218+
219+
if (!modernBrowser) {
220+
scripts.unshift('/polyfills.js');
221+
}
222+
223+
scripts.map(function(src) {
224+
var scriptElement = document.createElement('script');
225+
scriptElement.async = false;
226+
scriptElement.src = src;
227+
document.head.appendChild(scriptElement);
228+
});
229+
</script>
230+
```
231+
232+
T> Any script added dynamically like in the example above will run as soon as it's parsed, but we need our polyfill to run before our bundle. This is why we are setting `async` to `false` for each script.
233+
234+
235+
### Smaller babel polyfill
236+
237+
`babel-preset-env` uses [browserslist](https://github.com/ai/browserslist) to transpile only what is not supported in your browsers matrix. This preset comes with the `useBuiltIns` option _(false by default)_ which converts your global `babel-polyfill` import to a more granular feature by feature import pattern like:
238+
239+
```javascript
240+
import "core-js/modules/es7.string.pad-start";
241+
import "core-js/modules/es7.string.pad-end";
242+
import "core-js/modules/web.timers";
243+
import "core-js/modules/web.immediate";
244+
import "core-js/modules/web.dom.iterable";
245+
```

0 commit comments

Comments
 (0)