Search code examples
importmodulerequirejssynchronous

require.js synchronous loading


I'd like to define a module which computes a new dependancy, fetches it and then returns the result. Like so:

define(['defaults', 'get_config_name'], function(defaults, get_config_name) {
    var name = get_config_name();
    var config;
    require.synchronous([configs / '+name'], function(a) {
        config = defaults.extend(a);
    });
    return config;
});

Is there a way to do this or a better way to attack this problem?


Solution

    • You may try to use synchronous RequireJS call require('configs/'+get_config_name()), but it will load a module synchronously only if it is already loaded, otherwise it will throw an exception. Loading module/JavaScript file synchronously is technically impossible. UPD: It's possible (see Henrique's answer) but highly unrecommended. It blocks JavaScript execution that causes to freezing of the entire page. So, RequireJS doesn't support it.

    • From your use case it seems that you don't need synchronous RequireJS, you need to return result asynchronously. AMD pattern allows to define dependencies and load them asynchronously, but module's factory function must return result synchronously. The solution may be in using loader plugin (details here and here):

      // config_loader.js
      define(['defaults', 'get_config_name'], function(defaults, get_config_name) {
          return {
              load: function (resourceId, require, load) {
                  var config_name = 'configs/' + get_config_name();
                  require([config_name], function(config) {
                      load(defaults.extend(config));
                  })
              }
          }
      });
      
      // application.js
      define(['config_loader!'], function(config) {
          // code using config
      });
      
    • If get_config_name() contains simple logic and doesn't depend on another modules, the better and simpler is calculating on the fly paths configuration option, or in case your config depends on context - map configuration option.

      function get_config_name() {
          // do something
      }
      require.config({
          paths: {
              'config': 'configs/' + get_config_name()
          }
      });
      require(['application', 'defaults', 'config'], function(application, defaults, config) {
          config = defaults.extend(config);
          application.start(config);
      });