Require.JS + JQuery插件+客户托管的JQuery冲突

时间:2013-12-19 23:53:36

标签: javascript jquery requirejs

我们建立了一个类似于shopify的平台,我们在其中托管电子商务的客户网页。

在每个页面上,我们都有一些通过requireJS加载的平台javascript。

此平台javascript使用jquery Cookie作为插件。

如果客户也安装了jQuery,它可能导致Cookie插件将自己安装到jQuery的客户实例而不是我们的jQuery实例。

客户html:

<script type="text/javascript" src="/jquery.js"></script>

app.js [我们的代码]:

require.config({
    "paths": {
        "jquery": "bower_components/jquery/jquery.min",
        "jquery-cookie": "bower_components/jquery-cookie/jquery.cookie",
    },
    "shim": {
        "jquery-cookie": ["jquery"]
    }
});

platform.js [我们的代码]:

define(['jquery', 'jquerye-cookie'], function(jQuery, jQueryCookie) {
    console.dir(jQuery.cookie); // <-- Not available, sometimes
});

你可以在console.dir看到有时jQuery.cookie将不可用,这是因为jQuery cookie将自己安装到全局$中,这可能是客户的jQuery版本或我们的版本。

我唯一能解决的问题是始终使用我们平台js的编译版本。在生产中这很好,因为我们的代码是一起编译的,包括我们的jQuery依赖项,我们的代码执行顺序是确定性的,在加载时jQuery cookie安装到正确的jQuery对象中。

问题在于开发这是PITA只能在我们的平台js的编译版本上工作。仅仅编译时间就会让我们慢下来。

我正在讨论尝试在我们的平台JS中删除所有jQuery依赖项。我不想那样做,因为我也失去了欧芹。有没有更好的解决方案来避免这个问题?

更新

noconflict模式不起作用,因为jquery cookie(和其他jquery插件)的工作方式是:

(function ($, document, undefined) {
    $.cookie = function (key, value, options) {
    });
})(jQuery, document);

因为你可以看到,即使我将jQuery命名为“platform $”之类的命令,插件仍会将自身加载到window.jQuery中,这将是未定义的或客户的jQuery版本。

编辑:

要明确这不是“一个”客户,而是很多(最终成千上万,希望如此)。

2 个答案:

答案 0 :(得分:1)

当我查看jQuery cookie插件的current code时,我发现它检测到它是否在AMD风格的加载器(RequireJS是)中运行并使用define。这意味着这个插件不需要垫片。

现在,问题的失败怎么可能发生?

  • 客户端还使用RequireJS作为代码。这意味着将两个配置传递给RequireJS。他们可能会发生冲突。 RequireJS不是为了检测此类冲突而设计的。 (只要得到的配置对RequireJS有意义,它就不会抱怨。)并且根据两种配置的加载方式,结果可能是不确定的。

  • 客户端不会将RequireJS用于其代码。如果这个客户端在他们自己的代码中包含jQuery cookie插件,这可能会产生问题,因为在他们的插件版本时没有告诉$的价值是什么载入。

答案 1 :(得分:0)

您是否允许客户向页面添加任何HTML内容...?一般来说,出于安全原因,这是一个糟糕的主意,加上这样的情况,一个完全无辜的用户意外地破坏了你的网站。您可以尝试在noconflict模式http://learn.jquery.com/using-jquery-core/avoid-conflicts-other-libraries/中运行jquery,但如果客户可以输入任何旧的javascript,他们总会有办法破坏您网站的javascript。所以我认为真正的答案是限制客户可以输入的内容。