Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to use onLoad to start my webpack bundled code?

We are seeing some strange things in production that we don't seem to see in dev.

We have a few modules that are "external" to webpack,

  1. our locale translation strings (loaded separately based on selected locale)
  2. React itself (loaded from cdnjs)
  3. Another couple of externals (loaded from cdnjs)

The errors we are seeing (via Sentry) are that the resourceBundle can't be found, OR that React can't be found.

I'm wondering if this could be caused by not waiting for the onLoad event before we start the code in our entry point file. I had been assuming that webpack was dealing with the onLoad, but it appears (after searching thru the file webpack output) that that is not the case. In which case I need to wrap my code in an iffe so that it waits for all the externals to be present.

Then comes es6 and the import statement and I'm wondering how I manage to wrap that code in an iffe since imports have to be at top level.....

I know the browser has not changed, that onLoad is still important, but is webpack dealing with this in some subtle way I just overlooked, or do I need to go in and add that to my code. And if I need to add it, how do I deal with the es6 import in that case?

like image 427
boatcoder Avatar asked Dec 08 '22 20:12

boatcoder


1 Answers

Yes, webpack won't do anything to wait for your code to run. It executes as soon as the code is loaded. This is a good thing for flexibility, but means you have to add the handler yourself (NBD).

If you look at the bootstrap.js file on the FEM/01.4-transpile branch in the es6-todomvc project (used for my Frontend Masters course on Webpack), you'll notice that I'm using an $on helper which is adding a load event listener to window. Having a single (small) file that's responsible for starting up the app when the app has finished loading is a good approach IMO.

Here's another example:

function ready(fn) {
  if (document.readyState != 'loading'){
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

ready(function() {
  // start up your app
})

If you have jQuery, you don't need the ready function and could simply do:

$(function() {
  // start up your app
})

As for ESModules at the top of the file, my main tip is the general principle that your modules should not do anything when imported. Perhaps set up some variables, but other than that they should export functions only. This makes them easier to test as well as use in situations like this, so you could do:

import startApp from './start-app'

ready(startApp)

Good luck!

like image 129
kentcdodds Avatar answered Dec 10 '22 11:12

kentcdodds