【问题标题】:Trouble with Dojo Build and Conversion to AMDDojo 构建和转换到 AMD 的问题
【发布时间】:2016-01-22 13:35:18
【问题描述】:

我正在开发由其他人编写的 Dojo 应用程序。我是 Dojo 的新手,但发现要减少 http 请求,我需要生成一个“构建”版本。我已经这样做了,AFAICT(我至少得到了一个压缩脚本),但是当使用构建的脚本时,以前可用的函数都不起作用(它们是“未定义的”)。

此外,在试图弄清楚这一点时,看起来这将是使代码与 AMD 兼容的一个好点(此代码与 AMD 兼容吗?)。这将如何与以下示例一起使用?从阅读看来,我可能需要将每个现有函数从这样的脚本变成一个模块,这会产生数百个脚本,而且感觉不对。如何最好地转换这样的代码,使其与 AMD 兼容和可构建?

我有 15 个左右的 .js 脚本,它们都包含不同数量的以这种方式编写的函数...

TIA!

var somethingStatus = false;

somethingInit();

function somethingInit() {

    require(["dojo/ready", "dojo/dom", "dojo/dom-construct", "dojo/cookie", "dojo/json", "dojo/domReady!"], function(ready, dom, domConstruct) {

        ready(function() {

            var content = '';
            // content generated here, then...

            domConstruct.place(content, dom.byId('body'));

        });

    });

}

function somethingToTop(target) {

    require(["dojo/dom", "dojo/dom-style", "dojo/_base/fx", "dojo/window", "dojo/domReady!"], function(dom, domStyle, fx, win) {

        var vs = win.getBox();

        somethingBarStatus = true;

        fx.animateProperty({
            node: dom.byId('somethingBar'),
            properties: {
                top: { start: domStyle.get('somethingBar', 'top'), end: 0 },
                height: { start: domStyle.get('somethingBar', 'height') + (domStyle.get("somethingBar", "padding") * 2), end: vs.h }
            },
            duration: 500,
            onEnd: function() {
                document.location = 'http://192.168.0.1' + target;
            }
        }).play();

    });

}

function somethingEmptyTop() {

    require(["dojo/dom", "dojo/dom-construct", "dojo/domReady!"], function(dom, domConstruct) {

         globalContainerEmpty('somethingTop'); // this function is in another .js file, constructed similarly to this

    });

}

// many more functions like this below and across other scripts!

【问题讨论】:

    标签: javascript dojo amd


    【解决方案1】:

    在从 AMD 之前的 Dojo 迁移到 Dojo 1.7 时,您会遇到一个常见问题,即许多人会尝试在构建中运行完全不是模块的脚本。 Dojo 构建工具实际上是为适应模块而设计的,而不是松散的脚本,但是这种事情发生在“Just Work”之前。

    在上面的示例中,您的脚本似乎只定义了一些全局函数。如果有的话,它是正确模块的反面,因为每个单独的函数都涉及到自己的 require 调用。

    当 Dojo 构建遇到它检测到的不是 AMD 格式的文件时,它会在其周围放置一个 AMD 包装器,目的是调整使用 dojo.provide、dojo.require 和全局的适当的旧 Dojo 模块dojo 和 dijit 之类的命名空间。问题是,当脚本中的这些“全局”函数被包装时,它们成为包装器中 define 工厂的本地函数,因此不再是全局的。

    上述代码的正确转换如下所示:

    define([
        'dojo/_base/fx',
        'dojo/cookie',
        'dojo/dom',
        'dojo/dom-construct',
        'dojo/dom-style',
        'dojo/json',
        'dojo/window',
        'my/otherModule',
        'dojo/domReady!'
    ], function (fx, cookie, dom, domConstruct, domStyle, JSON, win, otherModule) {
    
        var somethingStatus = false;
    
        var util = {
            somethingInit: function () {
                var content = '';
                // content generated here, then...
    
                domConstruct.place(content, dom.byId('body'));
            }
    
            somethingToTop: function (target) {
                var vs = win.getBox();
    
                somethingBarStatus = true;
    
                fx.animateProperty({
                    node: dom.byId('somethingBar'),
                    properties: {
                        top: { start: domStyle.get('somethingBar', 'top'), end: 0 },
                        height: { start: domStyle.get('somethingBar', 'height') + (domStyle.get("somethingBar", "padding") * 2), end: vs.h }
                    },
                    duration: 500,
                    onEnd: function() {
                        document.location = 'http://192.168.0.1' + target;
                    }
                }).play();
            },
    
            somethingEmptyTop: function () {
                // assuming that the other module was converted similarly to this one
                otherModule.globalContainerEmpty('somethingTop');
            }
        };
    
        util.somethingInit();
        return util;
    }
    
    • 请注意,以前在每个单独函数中的所有依赖项都已在此模块的 define 调用中收集。
    • 由于 dojo/domReady,AMD 通常不需要 dojo/ready!已经在等待 DOMContentLoaded(或等效),而 define 工厂已经在等待模块加载完毕。

    然后,您可以通过在另一个模块中通过define 或在页面脚本中通过require 加载该模块上的每个函数来访问该模块上的每个函数,然后通过您存储模块的变量引用这些函数。(在此示例中,otherModule 是使用另一个转换模块的示例,因为您建议 globalContainerEmpty 在另一个类似的脚本文件中。)

    modules tutorial 有望提供进一步的帮助,modern Dojo 教程也可能提供。

    【讨论】:

    • 谢谢,肯。这实际上有某种意义(对我而言),并给了我一些新的热情!
    • 查看 Dojo 模块教程 - 将函数包装在 'var util = {...}' 和使用 'util = somethingInit();' 中的示例之间是否存在特殊差异,以及用 return{...} 代替?
    • 糟糕,在我的示例中,这看起来像是一个错字。我打算像您的示例一样立即运行util.somethingInit();,然后运行return util;。我会解决的。 (这是我创建变量的唯一原因,所以我可以自行引用它。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 2014-12-12
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多