【问题标题】:"TypeError: deps.map is not a function" in resolveDepMaps() of node_modules/dojo/dojo.jsnode_modules/dojo/dojo.js 的 resolveDepMaps() 中的“TypeError:deps.map 不是函数”
【发布时间】:2015-03-27 21:40:57
【问题描述】:

我一直在更改我组织的底层基础架构,以将我们的自动化测试从使用单独的 Web 服务器在浏览器客户端中运行切换到在测试运行程序(实习生运行程序)中运行。在测试运行器环境中,事情进展顺利——我已经解决了很多问题,但随后繁荣!有人丢弃了一个新的单元测试,它在浏览器客户端中运行得很好,但是当我用测试运行器运行它时,我得到了这个错误:

! TypeError: deps.map 不是http://9.77.140.51:9000/__intern/node_modules/dojo/dojo.js:678的函数

dojo.js 中的第 678 行是这样的:

resolveDeps = function (deps, module, referenceModule) {
    // resolve deps with respect to this module
    return deps.map(function (dep, i) {   // <-- Line 678!
        var result = getModule(dep, referenceModule);
        if (result.fix) {
            result.fix = function (m) {
                module.deps[i] = m;
            };
        }
        return result;
    });
},

我根本没有改变这个文件。我不知道 resolveDeps() 函数的作用或“deps”是什么。

我看不出这个新测试有什么不寻常的地方,与其他数百个测试都很好通过的测试相比,没有什么特别之处(但是,我没有写它)。浏览器客户端没有报告错误。使用测试运行程序运行时,打开开发人员工具查看控制台没有提供任何有意义的信息,因为 TypeError 似乎杀死了 HTTP 代理服务器,而浏览器控制台只显示了一堆 404,这看起来像红鲱鱼,因为服务器已停止。

谁有线索?

【问题讨论】:

    标签: dojo intern


    【解决方案1】:

    这可能是由于测试模块的格式不正确,尽管如果没有更多信息很难说。该错误发生在加载程序的依赖解析代码中,该代码对definerequire 语句起作用。 Dojo 的 define 函数理解 4 种参数配置:

    1. define(id, deps, callback)
    2. define(deps, callback)
    3. define(callback)
    4. define(object)

    id 是一个字符串,deps 是一个数组。)如果由于某种原因您有一个使用格式 define(id, callback) 的模块,您会收到您看到的错误,因为依赖解析代码加载器中的第一个或第二个参数是一个数组。

    【讨论】:

    • 谢谢,杰森。我通过逐渐删除 tdd.test() 调用和其他函数来缩减测试模块;最后,当它几乎是空的并且错误不断发生时,我从依赖数组中删除了一项并且 TypeError 消失了。当然,这是不可行的,因为测试调用了该模块上的函数;也许这个应用程序模块是小部件代码而不是“后端”业务逻辑代码很重要?实习生对小部件模块有任何问题吗?例如,它返回“declare("CustomWidget", [ContentPane, TemplatedMixin, WidgetsInTemplateMixin], { ..."? ?
    • 在我输入了几分钟后,我意识到,我正在尝试运行一个加载依赖于 DOM 的代码的测试——这在使用实习生运行时不可用。所以,虽然我得到的 TypeError 没有说出来,但这最终是问题所在,对吧?
    • 您可以使用 intern-runner 运行基于 DOM 的单元测试(suites 列表中的内容),但不能使用功能测试,因为单元测试将在浏览器中运行,而功能测试在 Node 中运行.
    • 在任何情况下,尝试在错误的环境(节点与浏览器)中加载模块都不会产生您所看到的错误。
    • Dojo 实际上使用了另一个配置,define(id, object),目前 Intern 不支持。
    【解决方案2】:

    这似乎是由dojo.js引起的

    这为测试提供了与非测试文件略有不同的模块加载路径。

    node_modules/dojo/dojo.js

      if (has('host-browser')) {
    injectUrl = function (url, callback, module, parent) {
        // insert a script element to the insert-point element with src=url;
        // apply callback upon detecting the script has loaded.
        var node = document.createElement('script'),
            handler = function (event) {
                document.head.removeChild(node);
    
                if (event.type === 'load') {
                    has('loader-ie9-compat') ? callback(node) : callback();
                }
    

    当Dojo 设置define 全局调用时,它会检查传递给define 调用的参数数量。所以,如果你传递一个对象来定义,类似于 nls 对 i18n 文件所做的事情,它将达到以下逻辑。

    node_modules/dojo/dojo.js:844

    var define = mix(function (deps, factory) {
        if (has('loader-explicit-mid') && arguments.length === 3) {
            var id = deps;
            deps = factory;
            factory = arguments[2];
            var module = getModule(id);
            module.injected = true;
            defineModule(module, deps, factory);
        }
    
        if (arguments.length === 1) {
            if (has('loader-cjs-wrapping') && typeof deps === 'function') {
                factory = deps;
                deps = [ 'require', 'exports', 'module' ];
    
                // Scan factory for require() calls and add them to the
                // list of dependencies
                factory.toString()
                    .replace(comments, '')
                    .replace(requireCall, function () {
                        deps.push(/* mid */ arguments[2]);
                    });
            }
            else if (/* define(value) */ !Array.isArray(deps)) {
                var value = deps;
                deps = [];
                factory = function () {
                    return value;
                };
            }
        }
    
        if (has('loader-ie9-compat')) {
            for (var i = document.scripts.length - 1, script; (script = document.scripts[i]); --i) {
                if (script.readyState === 'interactive') {
                    script.defArgs = [ deps, factory ];
                    break;
                }
            }
        }
        else {
            defArgs = [ deps, factory ];
        }
    }, {
        amd: { vendor: 'dojotoolkit.org' }
    });
    

    这里定义了如果不是函数,则进入第二次检查依赖项是否不是数组,然后建立结构体返回工厂中的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-12
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      • 1970-01-01
      • 2022-08-24
      • 1970-01-01
      相关资源
      最近更新 更多