How to declare dependencies inside an amd compatability check without creating 404/mismatched anonymous module during builds?

StackOverflow https://stackoverflow.com/questions/18935042

Frage

I'm struggling to add a plugin using the following AMD compatability setup to my application:

The snippet from foo.js in question:

(function (dependencies, module) {
  "use strict";
  if (typeof define === 'function' && define.amd) {
    return define(dependencies, module);
  }
  if (typeof exports === 'object') {
    return module(exports);
  }
  window.foo = {};
  module(window.foo, {hex_sha256: hex_sha256});
}(['exports', 'sha256'], function (exports, sha256) {

 // foo

 }));

I'm setting foo as a dependency in another module called bar like so:

define(["jquery", "foo", "sha256", "c", "d"], function() {
   // stuff
});

And inside the r.js optimizer I define bar to be:

  {
      name: "bar"
    , include: ["foo", "sha256", "c", "d"]
    , exclude: ["jquery"]
  },

This generates the bar.js file allright including the abovementioned files.

However when I load my built application, there are still two requests being triggered to foo.js and sha256.js, which both 404 (optimizer cleans up built files) and who are inside my bar.js build layer.

Question:
I'm a little lost with the module amd check and am suspecting it being responsible for the unwanted call. Can anyone shed some light on what I should modify in the AMD check to make foo callable form inside a build layer?

Thanks!

EDIT:
I tried shimming like so:

shim: {
  'foo':              { deps: ['sha256'] }
},

which takes care of the 404, but returns an:

Mismatched anonymous define() module: function (exports, sha256) {....

error, so I'm still stuck assuming the hardcoded dependency to sha256 in my AMD check to be the culprit. Maybe this helps.

EDIT:
I'm pretty sure my problems stem from the dependency declaration inside the AMD compatability check.

War es hilfreich?

Lösung

The two solutions below require modifications to the source of foo. Since you can control it, they are both viable:

  1. (Quick and dirty) Hardcode the module name in the define call:

    // foo.js
    if (typeof define === 'function' && define.amd) {
        return define("foo", dependencies, module);
    }
    
  2. (Cleaner) See the code of Knockout.js at the beginning. I am using it in a project and it seems to compile good with r.js. I tried a simple project setup like yours, and it works; so you have to replace the AMD compatibility code as follows:

    (function(factory) {
        // Support three module loading scenarios
        if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
            // [1] CommonJS/Node.js
            var target = module['exports'] || exports; // module.exports is for Node.js
            var hex_sha256 = require("sha256");
            factory(target, hex_sha256);
        } else if (typeof define === 'function' && define['amd']) {
            // [2] AMD anonymous module
            define(['exports','sha256'], factory);
        } else {
            // [3] No module loader (plain <script> tag) - put directly in global namespace
            factory(window['foo'] = {}, hex_sha256);
        }
    }(function(exports, sha256){
    
        // same foo
    
    }));
    

I do not know what magic happens inside r.js and this works...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top