Skip to content
This repository has been archived by the owner on Oct 16, 2021. It is now read-only.

Commit

Permalink
feat: Dynamically import and lazy load polyfills
Browse files Browse the repository at this point in the history
Related to micromata/Baumeister#235

This keeps the vendor bundle in modern browser smaller because
polyfills are only loaded when the used browser actually needs them.
  • Loading branch information
mischah committed Mar 22, 2018
1 parent 1627485 commit ef5f6b5
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 133 deletions.
4 changes: 2 additions & 2 deletions app/templates/_README.md
Expand Up @@ -616,11 +616,11 @@ We recommend using a command line tool like »[npm-check-update](https://github.

## Adding polyfills

The file `src/app/base/polyfills.js` is prepared to import polyfills you might need depending on your use of modern JavaScript language features and your target browsers.
The file `src/app/base/polyfills.js` is prepared to dynamic import polyfills you might need depending on your use of modern JavaScript language features and your target browsers. This way the polyfills are lazy loaded only in case the used browser actually needs them.

Just import the ones you need for the browsers you are targeting.

The only polyfill activated by default is a Promises polyfill which is needed if you use Promises and targeting Internet Explorers.
The only polyfill activated by default is a Promises polyfill which is needed for lazy loading polyfills in Internet Explorers.

## Unit tests

Expand Down
2 changes: 2 additions & 0 deletions app/templates/_package.json
Expand Up @@ -59,7 +59,9 @@
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-eslint": "^8.2.1",
"babel-loader": "^7.1.2",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-regenerator": "^6.26.0",
"babel-plugin-transform-runtime": "^6.23.0",
Expand Down
1 change: 1 addition & 0 deletions app/templates/babelrc
@@ -1,6 +1,7 @@
{
"presets": ["env"],
"plugins": [
"syntax-dynamic-import",
"transform-object-rest-spread",
[
"transform-runtime",
Expand Down
3 changes: 2 additions & 1 deletion app/templates/build/webpack.dev.babel.js
Expand Up @@ -12,7 +12,8 @@ module.exports = require('./webpack.base.babel')({
},
output: {
path: path.join(__dirname, mainDirectories.dev),
filename: 'app/[name].bundle.js'
filename: 'app/[name].bundle.js',
chunkFilename: 'app/[name].bundle.js'
},
plugins: [
new webpack.SourceMapDevToolPlugin({
Expand Down
3 changes: 2 additions & 1 deletion app/templates/build/webpack.prod.babel.js
Expand Up @@ -40,7 +40,8 @@ module.exports = require('./webpack.base.babel')({
},
output: {
path: path.join(__dirname, mainDirectories.prod),
filename: configFile.cacheBusting ? 'app/[name].[chunkhash].bundle.js' : 'app/[name].bundle.js'
filename: configFile.cacheBusting ? 'app/[name].[chunkhash].bundle.js' : 'app/[name].bundle.js',
chunkFilename: configFile.cacheBusting ? 'app/[name].[chunkhash].bundle.js' : 'app/[name].bundle.js'
},
plugins: [
new UglifyJSPlugin({
Expand Down
8 changes: 5 additions & 3 deletions app/templates/eslintrc.json
@@ -1,10 +1,12 @@
{
"extends": "baumeister",
"parser": "babel-eslint",
"parserOptions": {
"allowImportExportEverywhere": true
},
"overrides": [
{
"files": [
"build/*.js"
],
"files": ["build/*.js"],
"rules": {
"no-console": "off",
"unicorn/no-process-exit": "off"
Expand Down
167 changes: 47 additions & 120 deletions app/templates/src/app/base/polyfills.js
Expand Up @@ -3,27 +3,19 @@
* Please only add those you are actually using. Otherwise you’ll unnecessarily
* blow up the size of your JS bundle.
*
* You can add your own extra polyfills to this file:
* Check https://github.com/zloirock/core-js to see whats available.
* You can add your own additional polyfills to this file:
* See https://github.com/zloirock/core-js to see whats available.
*
* Check what your target browsers need (https://kangax.github.io/compat-table/es6/)
* and use dynamic imports like in the examples below. This way the polyfills
* are lazy loaded only when a browser actually needs them.
*/

/**
* ----------------------------------------------------------------------------
* Import each and every polyfill provided by core-js
* -----------------------------------------------------------------------------
* This is for the lazy ones and absolultely not recommended because it will
* increase your JS bundle by more than 120 kb (minified). Better check what
* your target browsers need (https://kangax.github.io/compat-table/es6/)
* and use partial imports like in the examples below.
*/
// import 'core-js';

/**
* ----------------------------------------------------------------------------
* Promises. Mainly needed for Internet Explorer up to IE11
* -----------------------------------------------------------------------------
* Promises are needed to lazy load addtional polyfills in case they are
* Promises are needed to lazy load additional polyfills in case there are
* needed. We are using https://github.com/taylorhakes/promise-polyfill instead
* of the polyfill provided by core-js to keep the vendor bundle as small as
* possible. This one adds 3.19 kB minified and 1.23 kB minified and gzipped.
Expand All @@ -36,126 +28,61 @@ import 'promise-polyfill/src/polyfill';

/**
* ----------------------------------------------------------------------------
* Additional ES6 polyfills
* Definition of dynamically imported polyfills
* -----------------------------------------------------------------------------
*/

/**
* Import all object methods.
* See https://github.com/zloirock/core-js#ecmascript-6-object how to import
* just the ones you need.
*/
// import 'core-js/es6/object';
export const applyPolyfills = () => {

/**
* Import all function methods.
* See https://github.com/zloirock/core-js#ecmascript-6-function how to import
* just the ones you need.
*/
// import 'core-js/es6/function';
const polyfills = [];

/**
* Import all array methods.
* See https://github.com/zloirock/core-js#ecmascript-6-array how to import
* just the ones you need.
*/
// import 'core-js/es6/array';
/**
* Globals
*/

/**
* Import all string methods.
* See https://github.com/zloirock/core-js#ecmascript-6-string how to import
* just the ones you need.
*/
// import 'core-js/es6/string';
// if (typeof Object.assign !== 'function') {
// polyfills.push(import(/* webpackChunkName: "Object.assign" */ 'core-js/fn/object/assign'));
// }

/**
* Import all regexp methods.
* See https://github.com/zloirock/core-js#ecmascript-6-regexp how to import
* just the ones you need.
*/
// import 'core-js/es6/regexp';
// if (!window.Set) {
// polyfills.push(import(/* webpackChunkName: "set" */ 'core-js/es6/set'));
// }

/**
* Import all number methods.
* See https://github.com/zloirock/core-js#ecmascript-6-number how to import
* just the ones you need.
*/
// import 'core-js/es6/number';
// if (!window.Map) {
// polyfills.push(import(/* webpackChunkName: "map" */ 'core-js/es6/map'));
// }

/**
* Import all math methods.
* See https://github.com/zloirock/core-js#ecmascript-6-math how to import
* just the ones you need.
*/
// import 'core-js/es6/math';
/**
* Array prototype methods
*/

/**
* Import all date methods.
* See https://github.com/zloirock/core-js#ecmascript-6-date how to import
* just the ones you need.
*/
// import 'core-js/es6/date';
// if (!Array.prototype.includes) {
// polyfills.push(import(/* webpackChunkName: "Array.prototype.includes" */ 'core-js/fn/array/includes'));
// }

/**
* Import all collection types.
* See https://github.com/zloirock/core-js#ecmascript-6-collections.
*/
// import 'core-js/es6/map';
// import 'core-js/es6/set';
// import 'core-js/es6/weak-map';
// import 'core-js/es6/weak-set';
// if (!Array.prototype.find) {
// polyfills.push(import(/* webpackChunkName: "Array.prototype.find" */ 'core-js/fn/array/find'));
// }

/**
* Import all typed-array methods.
* See https://github.com/zloirock/core-js#ecmascript-6-typed-arrays how to import
* just the ones you need.
*/
// import 'core-js/es6/typed';
/**
* String prototype methods
*/

/**
* Import all reflect methods.
* See https://github.com/zloirock/core-js#ecmascript-6-reflect how to import
* just the ones you need.
*/
// import 'core-js/es6/reflect';

/**
* ----------------------------------------------------------------------------
* Additional ES7+ polyfills
* -----------------------------------------------------------------------------
*/

/**
* Import all ES7 polyfills,
* See https://github.com/zloirock/core-js#ecmascript-7-proposals how to import
* just the ones you need.
*/
// import 'core-js/es7';

/**
* Import all polyfills of stage 4 proposals
*/
// import 'core-js/stage/4';
// if (!String.prototype.includes) {
// polyfills.push(import(/* webpackChunkName: "String.prototype.includes" */ 'core-js/fn/string/includes'));
// }

/**
* Import all polyfills of stage 3 proposals
* See https://github.com/zloirock/core-js#ecmascript-7-proposals how to import
* pre stage 3 polyfills.
*/
// import 'core-js/stage/3';
// if (!String.prototype.startsWith) {
// polyfills.push(import(/* webpackChunkName: "String.prototype.startsWith" */ 'core-js/fn/string/starts-with'));
// }

/**
* ----------------------------------------------------------------------------
* Examples for method based imports
* -----------------------------------------------------------------------------
*/
// if (!String.prototype.trimStart) {
// polyfills.push(import(/* webpackChunkName: "String.prototype.trimStart" */ 'core-js/fn/string/trim-start'));
// }

/**
* Import a single string method
*/
// import 'core-js/fn/string/trim-start';
// if (!String.prototype.trimEnd) {
// polyfills.push(import(/* webpackChunkName: "String.prototype.trimEnd" */ 'core-js/fn/string/trim-end'));
// }

/**
* Import a single array method
*/
// import 'core-js/fn/array/includes';
return Promise.all(polyfills);
};
13 changes: 7 additions & 6 deletions app/templates/src/app/index.js
Expand Up @@ -10,19 +10,20 @@ import 'bootstrap';
// import 'bootstrap/js/dist/dropdown';

// Import polyfills
import './base/polyfills';
import {applyPolyfills} from './base/polyfills';

// Import methods from the base module
import {
consoleErrorFix,
ieViewportFix
} from './base/base';
import {consoleErrorFix, ieViewportFix} from './base/base';

// Import our Sass entrypoint to create the CSS app bundle
import '../assets/scss/index.scss';

$(() => {
$(async () => {
// Wait with further execution until needed polyfills are loaded.
await applyPolyfills();

consoleErrorFix();
ieViewportFix();

console.log('YaY, my first ES6-Module !!!!');
});

0 comments on commit ef5f6b5

Please sign in to comment.