2

Now here is a little pickle I have yet so solve properly.

I authored a Wordpress plugin and it uses requirejs for loading javascript modules. All is well, until occasionally I get very obscure error reports form users. As it turns out, when other themes or plugins also had the bright idea of using requirejs you get the infamous "mismatch anonymous define() modules (problem)[http://www.requirejs.org/docs/errors.html#mismatch] due two several instances of requirejs itself.

Is there any way around this?

    2 Answers 2

    1

    You could take a look at the enqueued scripts in $wp_scripts ($wp_scripts->registered), but the naming could be different ("it's requirejs but let's call it loadstuffjs, just because"), so I doubt it'll be close to perfect.

    Also, your plugin might be loaded before the other plugin, and they might trigger the problem without you having any control.

    Maybe make loading requirejs optional (but enabled) and tell people that they ought to try disable loading it if they run into this problem (the reason being that the "other" requirejs will be loaded and work just fine). Also, I'd get a list of plugin/themes that you have these problems with and inform the user about incompatibility and ask whether they want to enable your "compatibility mode" (aka not loading requirejs through your plugin).

    2
    • I neither want to rely on what other developers call their script nor want users to have to enable this compatibility mode. What I am looking for is a solution somehow with requirejs itself that would detect if it is already present.
      – kontur
      CommentedOct 15, 2017 at 19:13
    • I think that would be better suited as a feature request for requirejs. Even if you patched the version you ship with your plugin, it'll probably still break if the original version gets loaded by another plugin/theme after yours.
      – janh
      CommentedOct 15, 2017 at 19:41
    1

    After some long searching there appears to be a way.

    First of all, this means using the requirejs optimiser, i.e. pre-compiling the module, possibly into a single minified file.

    Secondly, in the optimiser options there is a namespace option, which essentially prefixes all require, define and module calls, so they no longer interfere with another requirejs present on the site.

    So calling $ node r.js -o build.js with the following build.js file:

    ({ paths: { 'modulename': 'path/to/modulefile', 'modulename': 'path/to/modulefile', 'modulename': 'path/to/modulefile', 'requireLib': 'path/to/requirejs' }, name: "js/main", out: "js/bundle.js", include: "requireLib", namespace: "mynamespace", }) 

    will transform the module defined in js/main.js to js/bundle.js in minified form and including all required modules and all require() calls in that minified file will be mynamespace.require() calls in the output file.

    The include option is important so that the optimiser will actually include requirejs itself in the bundle, and calling it something else than just "require" (i.e. "requireLib") is required so the optimiser internally doesn't get confused.

    Finally, this file has all available optimizer build.js options.

    It is insane to think that any plugin or theme author using requirejs should be aware of this, and in fact I think most developers aren't until they hit this incompatibility combination with another plugin or theme. This, however, is a way to be certain that requirejs won't cause problems when used in a Wordpress project.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.