thorstorm
thorstorm

Reputation: 153

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!

Upvotes: 0

Views: 143

Answers (2)

Louis
Louis

Reputation: 151380

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.

Upvotes: 1

David Knipe
David Knipe

Reputation: 3454

When requirejs receives a script from the network, it runs that script. the require (or define?) function says "download these other scripts, then run them, and once you've got all their return values, run this function". So it waits for the other scripts to load and return their values before calling the function in this one. In short, the order in which they load may not be the same as the order in which their functions run.

Upvotes: 1

Related Questions