Skip to content

Instantly share code, notes, and snippets.

@gcoda
Last active January 25, 2017 16:18
Show Gist options
  • Save gcoda/7434f2afcbd268b23f2aabcaa8eabe68 to your computer and use it in GitHub Desktop.
Save gcoda/7434f2afcbd268b23f2aabcaa8eabe68 to your computer and use it in GitHub Desktop.
webpack, load app.js after bundle.js async

webpack config will produce something like

<script type="text/javascript" src="/dist/vendor.0fcb27d1250abb1c9f24.js" async></script>
<script type="text/javascript" src="/dist/app.0fcb27d1250abb1c9f24.js" defer></script>

and while serving index.html i am replacing it with:

<script type="text/javascript" src="/dist/vendor.0fcb27d1250abb1c9f24.js" async></script>
<script type="text/javascript" async>
  var load = function() {
    if (window.__VENDOR_LOADED__){
      var script = document.createElement('script');
      script.async = true;
      script.src = '/dist/app.0fcb27d1250abb1c9f24.js';
      document.head.appendChild(script);
    } else {
      setTimeout(load, 10);
    }
  }
  load();
</script>
function injectReady (source, needle) {
return ` <script type="text/javascript" async>
var load = function() {
if (window.__VENDOR_LOADED__){
var script = document.createElement('script');
script.async = true;
script.src = '${needle}';
document.head.appendChild(script);
} else {
setTimeout(load, 10);
}
}
load();
// document.addEventListener('DOMContentLoaded', load);
</script>`
}
function parseIndex (template) {
template = template.replace(/<script\stype="text\/javascript"\ssrc="(([A-Za-z0-9./_]*))"\sdefer><\/script>/, injectReady)
const contentMarker = '<!-- APP -->'
const i = template.indexOf(contentMarker)
return {
head: template.slice(0, i),
tail: template.slice(i + contentMarker.length)
}
}
/*
vendor-loaded.js just oneliner with ` window.__VENDOR_LOADED__ = true `
*/
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
module.exports = {
resolve: {
alias: {
'vendor-loaded': './src/vendor-loaded.js'
}
},
entry: {
app: './src/client-entry.js',
vendor: [
'es6-promise', // vuejs, bootstrap, etc...
'vendor-loaded',
'axios'
]
},
plugins: (base.plugins || []).concat([
new ScriptExtHtmlWebpackPlugin({
defer: [/app/], // it will put defer attr on app scripts
defaultAttribute: 'async' // and async on all else
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment