为什么简化的CommonJS Wrapper语法在我的Dojo AMD模块上不起作用

Why is the Simplified CommonJS Wrapper syntax not working on my Dojo AMD module?

本文关键字:Dojo 我的 AMD 模块 不起作用 语法 CommonJS Wrapper 为什么      更新时间:2023-09-26

我开始考虑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包装器结构时:

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")
    }
})

dojo完全支持Simplified 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...
});

这里有一个关于Dojo定义的小包装器,它使用从RequireJS中获取的代码来计算基于定义函数的toString的依赖关系。它将当前的"define"封装在全局命名空间中,计算依赖项,然后调用封装的define。

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>

请注意,在进行构建时,Dojo不支持用于依赖项检测的简化CommonJS样式。这意味着您要么需要使用普通的依赖项列表样式,要么在构建配置文件中定义层时必须复制所有依赖项。

以下是他们跟踪器中的相关错误:

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

是否定义了require?我看不出这个论点的价值会从哪里来。我想你可能不得不做一些类似的事情

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

我开始想,也许我不应该学习Dojo。但是,这一切都与更多的阅读结合在一起。我不确定我到底做了什么不同,但这是工作布局。

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包装

Dojo工具包AMD

Dojo Config(1.7)