Почему синтаксис упрощенного CommonJS Wrapper не работает на моем модуле Dojo AMD? - PullRequest
5 голосов
/ 09 февраля 2012

Я начинаю оборачиваться вокруг requirejs и новой структуры Dojo AMD, но у меня проблема с некоторыми ранними тестами:

cg / signup.js:

define(['dojo/_base/fx', 'dojo/dom'], function(fx, dom){    
    return function(){
        this.hidePreloader = function(id){
            var preloader = dom.byId(id);
            fx.fadeOut({node : preloader}).play()
        }
    }
})

Это отлично работает.В основном файле cg.js:

require(['dojo/_base/kernel', 'dojo/_base/loader'])
dojo.registerModulePath('cg', '../cg')

require(['cg/signup', 'dojo/domReady!'], function(Signup){
        var sp = new Signup();
        sp.hidePreloader('preloader')
})

Бам.Готово.Однако при использовании структуры упрощенного CommonJS Wrapper:

define(function(require){    
    var fx = require('dojo/_base/fx'),
        dom = require('dojo/dom');

    return function(){
        this.hidePreloader = function(id){
            var preloader = dom.byId(id);
            fx.fadeOut({node : preloader}).play()
        }
    }
})

я получаю ошибку undefinedModule.Похоже, это происходит из строки dojo/_base/fx, но я не знаю почему.

ОБНОВЛЕНИЕ

Для уточнения.

Скрипты index.html

<script type="text/javascript" src="js/dojo/dojo.js.uncompressed.js" data-dojo-config="isDebug:true,async:true"></script>
<script type="text/javascript" src="js/cg.js"></script>

cg.js

require(['dojo/_base/kernel', 'dojo/_base/loader'])
dojo.registerModulePath('cg', '../cg')

require(['cg/signup', 'dojo/domReady!'], function(signup){
    signup.testFunc()
})

js / cg / signup.js

define(['require', 'exports'], function(require, exports){
    var dom = require('dojo/_base/kernel');
// Any other require() declarations (with very very few exceptions like 'dojo/_base/array throw undefinedModule errors!!!

    // without any error causing requires, this works fine.
    exports.testFunc = function(){
        alert("hello")
    }
})

Ответы [ 5 ]

3 голосов
/ 17 мая 2012

dojo полностью поддерживает формат Упрощенный CommonJS Wrapper. однако есть предварительное условие ... у вас не должно быть массива зависимостей.

define(function (require, exports, module) {
    var fx = require('dojo/_base/fx'),
        dom = require('dojo/dom');

    // continue...
});

это НЕ будет работать так же

define(['require', 'exports', 'module'], function (require, exports, module) {
    var fx = require('dojo/_base/fx'),
        dom = require('dojo/dom');

    // continue...
});

и это не будет ...

// in this case require, exports and module will not even exist
define([], function (require, exports, module) {
        var fx = require('dojo/_base/fx'),
        dom = require('dojo/dom');

    // continue...
});
2 голосов
/ 20 февраля 2013

Обратите внимание, что Dojo не поддерживает упрощенный стиль CommonJS для обнаружения зависимостей при выполнении сборки.Это означает, что вам нужно либо использовать обычный стиль списка зависимостей, либо дублировать все ваши зависимости при определении слоев в профиле сборки.

Вот соответствующая ошибка в их трекере:

http://bugs.dojotoolkit.org/ticket/15350

2 голосов
/ 25 февраля 2012

Вот небольшая оболочка для определения Dojo, которая использует код, взятый из RequireJS, для вычисления зависимостей на основе toString функции определения.Он оборачивает текущее определение в глобальном пространстве имен, вычисляет зависимости, а затем вызывает обернутое определение.

defineWrapper.js:

// Workaround for the fact that Dojo AMD does not support the Simplified CommonJS Wrapper module definition
(function() {
    var commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
      cjsRequireRegExp = /require\(\s*["']([^'"\s]+)["']\s*\)/g,
      ostring = Object.prototype.toString;
    function isArray(it) {
      return ostring.call(it) === '[object Array]';
    }
    function isFunction(it) {
      return ostring.call(it) === '[object Function]';
    }
    var oldDefine = define;

    define = function(name, deps, callback) {
        //Allow for anonymous functions
        if (typeof name !== 'string') {
          //Adjust args appropriately
          callback = deps;
          deps = name;
          name = null;
        }

        //This module may not have dependencies
        if (!isArray(deps)) {
          callback = deps;
          deps = [];
        }

        //If no name, and callback is a function, then figure out if it a
        //CommonJS thing with dependencies.
        if (!deps.length && isFunction(callback)) {
          //Remove comments from the callback string,
          //look for require calls, and pull them into the dependencies,
          //but only if there are function args.
          if (callback.length) {
              callback
                  .toString()
                  .replace(commentRegExp, '')
                  .replace(cjsRequireRegExp, function(match, dep) {
                      deps.push(dep);
                  });

              //May be a CommonJS thing even without require calls, but still
              //could use exports, and module. Avoid doing exports and module
              //work though if it just needs require.
              //REQUIRES the function to expect the CommonJS variables in the
              //order listed below.
              deps = (callback.length === 1 ? ['require'] :
                  ['require', 'exports', 'module']).concat(deps);
          }
        }

        if(name === null) {
            return oldDefine(deps, callback);
        } else {
            return oldDefine(name, deps, callback);
        }
    }
})();

Как бы вы его использовали?

<script src="...dojo..."></script>
<script src="defineWrapper.js"></script>
<script>require(["some_simplified_commonjs_defined_module"], function(module) {
   // use module here
});</script>
1 голос
/ 10 февраля 2012

Я начал думать, что, возможно, я не собирался изучать Додзё.Но все это идет вместе с немного больше чтения.Я не совсем уверен, что я сделал по-другому или что-то в этом роде, но вот рабочий макет.

index.html скрипты и конфиг

<script type="text/javascript">
dojoConfig = {
    async : true,
    isDebug : true,
    debugAtAllCosts : true,
    packages : [{
        name : 'cg',
        location : '/../js/cg'
    }]
}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js"></script>
<script type="text/javascript" src="js/cg.js"></script>

js/cg.js

require(['cg/signup', 'dojo/ready'], function(signup){
    signup.init('preloader')
})

js / cg / signup.js

define(['dojo', 'require'], function(dojo, require){
    var fx = require('dojo/_base/fx')

    return new function(){    
        this.init = function(id){
            fx.fadeOut({node : dojo.byId(id)}).play()
        }
    }
})

Опять не совсем уверен, почему работает оператор var fx = require(...)по-другому, чем у других, может быть сборка, которую я скачал, против CDN, кого это волнует.Оно работает.Некоторые ссылки, которые я использовал, чтобы помочь другим, возможно, в той же лодке:

Написание модульного JS

AMD против CommonJS Wrapper

Dojo Toolkit AMD

Dojo Config (1.7)

1 голос
/ 09 февраля 2012

определяется require?Я не вижу, откуда взялась бы ценность этого аргумента.Я думаю, что вам, возможно, придется сделать что-то вроде

define(["require"], function(require){ ...
...