Skip to content

Failure to build with asynchronous-loading plugin #604

@njoyard

Description

@njoyard

I'm working on a template library with requirejs plugin support. The plugin loads templates asynchronously and compiles them as AMD modules, and also has support for loading dependencies (ie. included templates). It works well in the browser but fails when building with r.js 2.1.10.

Basically I nailed down the issue to a simple test case. Here is the plugin code (an over-simplified copy of what requirejs-handlebars does, which is itself inspired by requirejs-text):

// myplugin.js
define(function() {
  // Simulate fetching module code asynchronously
  function getCode(name, callback) {
    var code;

    switch(name) {
      case 'first':
        code = 'define("myplugin!first", ["myplugin!second"], function(second) { return second.value; })';
        break;

      case 'second':
        code = 'define("myplugin!second", function() { return { value: "secondValue" }; });';
        break;
    }

    setTimeout(function() { callback(code); }, 100);
  }

  var buildMap = {};

  return {
    write: function(plugin, name, write) {
      if (name in buildMap) {
        write(buildMap[name]);
      }
    },

    load: function(name, req, onload, config) {
      getCode(name, function(code) {
        if (!code) {
          onload.error("Cannot find myplugin!" + name);
        } else {
          buildMap[name] = code;
          onload.fromText(code);
        }
      });
    }
  }
});

Here is the main code:

// main.js
require(['myplugin!first'], function(value) {
  console.log("Loaded module, value is " + value);
});

And the build configuration:

{
  "name": "main",
  "out": "main-built.js",
  "optimize": "none"
}

I get the following error when building :

$ node_modules/.bin/r.js -o build.conf 

Tracing dependencies for: main
Error: Error: Loader plugin did not call the load callback in the build:
myplugin:
  myplugin!first_unnormalized2
  myplugin!first
Module loading did not complete for: main
    at Function.build.checkForErrors (/home/niko/dev/rjs-test/node_modules/requirejs/bin/r.js:27064:19

Making the plugin near-synchronous (ie. replacing the setTimeout call with callback(code);) makes the build succeed.

Am I doing something wrong there, or is this a situation r.js cannot handle ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions