Search code examples
javascriptrequirejsload-order

requirejs unexpected behaviour


// conifg.js
require.config({
  paths: {
    'main': 'main',
    'socketio': './libs/socket.io/socket.io',
    'plotly': './libs/plotly/plotly-latest.min',
    'renderDataToPlotly': './scripts/renderDataToPlotly',
    'jquery': './libs/jquery/jquery-2.1.4.min',
    'jqueryUI': './libs/jquery/jquery-ui-1.11.4.custom/jquery-ui.min',
    'sliders': './scripts/sliders',
    'makePlotlyWindowResponsive': './scripts/makePlotlyWindowResponsive'
  },
  shim: {                  
    'jqueryUI': ['jquery'] 
  }
});

require(['main']);

// main.js
define([
  'jquery',
  'jqueryUI',
  'socketio',
  'sliders',
  'makePlotlyWindowResponsive',
  'renderDataToPlotly'
  ],
  function($, ui, io, sliders, makePlotlyWindowResponsive, renderDataToPlotly) {
    //
  }
);

// renderDataToPlotly.js and makePlotlyWindowResponsive.js
define(['plotly'], function() {

});

When I load the page I get this load order: enter image description here As you can see, makePlotlyWindowResponsive.js (1, on image) loads before plotly-latest.min.js (2, on image). As I understand requirejs mechanics, I would spect a Plotly is not defined error on makePlotlyWindowResponsive.js, but I'm not getting any. Everything works.

I want to understand requirejs and how it works.

Question 1: How there is not an error?

Question 2: That means that, despite load order, there is no error if files are loaded before page is fully loaded?

Thanks for your time!


Solution

  • The relative order you witnessed between plotly.min.js and the modules that depend on it is necessary. RequireJS has no reason to fetch plotly.min.js until makePlotlyWindowResponsive or renderDataToPlotly have been fetched.

    Terminological note: I say "fetching (a module)" for the action of issuing an HTTP query on the network and I'll use "defining (a module)" for the action of running the factory function of a module. The term "loading" is too ambiguous.

    What happens is:

    1. You require main. So RequireJS fetches main.

    2. RequireJS executes the define in main. The factory (the callback) cannot be run until the dependencies are defined themselves. So it initiates fetching the dependencies. This fetching can happen in any order. Among the dependencies are makePlotlyWindowResponsive and renderDataToPlotly.

    3. RequireJS fetches makePlotlyWindowResponsive and renderDataToPlotly. (Their relative order does not matter.)

    4. RequireJS executes the define of either makePlotlyWindowResponsive or renderDataToPlotly. This is where it learns that it must fetch the module plotly which resolves to ./libs/plotly/plotly-latest.min.js. Before this point, RequireJS has no idea that plotly will be needed. The fact that it is among the paths is not a sufficient condition to trigger its loading.

    5. RequireJS fetches ./libs/plotly/plotly-latest.min.js.