RequireJS Dependancies随机失败:"模块尚未加载上下文",令人费解

时间:2016-03-02 18:48:15

标签: requirejs

我经历了一个问题,在长时间(大约一年)工作正常后,RequireJS会在不同区域随机弹出一个问题。

我声明我的requireJS文件:

define(['TestController'], function (TestController) 
{
 return {

    oneFunction: function(callback)
    {
        //When I try to use "TestController" here, I get the 
        //"Error: Module name "TestController" has not been 
        //loaded yet for context" error...
        TestController.test(); //ERROR

        //I had been using the above for years, without changes, 
        //and it worked great. then out of the blue started not
        // working. Ok, let's try something else:
        if(typeof TestController == "undefined")
        {
            var TestController = require('TestController'); //ERROR
        }

        //The above method worked for a few months, then broke AGAIN
        // out of the blue, with the same error. My last resort is one
        // that always works, however it makes my code have about 20+ 
        //layers of callbacks:
        require(['TestController'], function(TestController){
            TestController.test(); 
            //WORKS, but what's the point of declaring it as a 
            //requirement at the top if it doesn't work and I have to 
            //wrap my code every time? :(
        });
    },

    anotherFunction: function()
    {
       console.log("hello");
    }
  }
});

我收到&#34;错误:模块名称&#34; TestController&#34;尚未加载上下文&#34; 错误,直到我 重新声明依赖 ...我的问题是, < em>宣告&#39; TestController&#39;的重点是什么?在顶部 作为依赖,如果我必须继续重新声明它,好像我从未列出它?我在这里做错了什么?

我宣布&#39; TestController&#39;在其他文件中,它工作得很好,但每隔一段时间,其中一个声明会失败......而且它总是一个不同的文件(大约有200-300)...我永远不知道哪一个,修复它的唯一方法是重新声明并包装它。

任何人都可以看到任何可能造成这种情况的错误吗?我一直在更新RequireJS以查看它是否修复了它并且它没有:/

    • RequireJS 2.1.22
    • 的jquery-1.12.1
    • node 4.2.6

1 个答案:

答案 0 :(得分:0)

正如@Louis指出的那样,导致问题的是循环依赖。

循环依赖解决方案#1:&#39; exports&#39;

这是直接来自RequireJS's documentation的解决方案:

  

如果你定义一个循环依赖(&#34; a&#34;需要&#34; b&#34;和&#34; b&#34;需要&#34; a&#34;),那么在此如果调用&#34; b&#34;的模块函数,它将获得&#34; a&#34;的未定义值。 &#34; B&#34;可以获取&#34; a&#34;稍后在使用require()方法定义模块之后(确保将require指定为依赖项,以便使用正确的上下文查找&#34; a&#34;):

//Inside b.js:
define(["require", "a"],
    function(require, a) {
        //"a" in this case will be null if "a" also asked for "b",
        //a circular dependency.
        return function(title) {
            return require("a").doSomething();
        }
    }
);
  

如果您熟悉CommonJS模块,则可以使用导出为模块创建一个空对象,该对象可立即供其他模块参考。

//Inside b.js:
define(function(require, exports, module) {
    //If "a" has used exports, then we have a real
    //object reference here. However, we cannot use
    //any of "a"'s properties until after "b" returns a value.
    var a = require("a");

    exports.foo = function () {
        return a.bar();
    };
});

循环依赖解决方案#2:使用madge可视化

我来到这个npm模块,它会为你创建一个依赖图:https://github.com/pahen/madge

我决定用madge分析我的代码并删除循环依赖项。

以下是我使用该工具的方法:

cd <Client-Code-Location>
madge --image dep.png .

这给了我一个依赖关系的图像,但是没有找到循环依赖关系。所以我决定尝试另一种方式:

cd <Client-Code-Location>
madge --image dep.png --format amd .

通过这种方式,我能够看到循环依赖的位置。 :)