0

我们的项目是一个非常庞大的单页企业应用程序,基于 RequireJS 和 Backbone.js,对于一些复杂的 UI,我们使用jqWidgets

特别是,这些 jqWidgets 是导致我们问题的原因。使用旧的 jqWidgets 3.3 实现了许多应用程序功能,对于所有新功能,我们希望使用 3.6,但是将旧功能移植到 3.6 非常棘手,并且会花费我们目前没有的时间。

为了节省这段时间,我们想要做的是让 3.3 和 3.6 一起工作而不会产生任何问题,并在以后有可能的情况下进行移植部分。

到目前为止我已经尝试过:

requirejs.config({
    paths: {
        "jquery": "vendor/jquery",
        "jqx": "vendor/jqwidgets/3.3",
        "jqx3.6": "vendor/jqwidgets/3.6",
        ... other libs...
    },
    shim: {
        ... other shims ...
        // jqWidgets3.3
        "jqx/jqxcore": {
             deps: ["jquery"]
        },
        "jqx/<<some_plugin>>": {
             deps: ["jqx/jqxcore"],
             exports: "$.fn.<<some_plugin>>"
        },
        // jqWidgets3.6
        "jqx3.6/jqxcore": {
             deps: ["jquery"]
        },
        "jqx3.6/<<some_plugin>>": {
             deps: ["jqx3.6/jqxcore"],
             exports: "$.fn.<<some_plugin>>"
        },
    }
});

旧功能中的用法:

require(["jquery", "jqx/<<some_plugin>>"], function($) {
     $('<<some_selector>>').<<some_plugin>>(...options...);
});

新功能中的用法:

require(["jquery", "jqx3.6/<<some_plugin>>"], function($) {
     $('<<some_selector>>').<<some_plugin>>(...options...);
});

由于这两个插件都应用于相同的 jQuery 对象,因此使用不同的名称/路径引用它们是可行的,但会产生很多错误。示例:如果您在应用程序中使用的第一个功能是使用 jqWidgets 3.3 加载的,那么使用 3.6 的下一个使用的功能可能会损坏,反之亦然。仅当您在每次使用功能后刷新页面时它才有效——这有点毫无意义,因为它是单页应用程序。

所以我的问题是:是否有可能让 jqWidgets 3.3 和 3.6 一起工作,然后依赖他们自己的 jQuery 对象,这样就不会发生这种冲突?

// 附录 1:我认为潜在的解决方案在于对这个问题的评论:RequireJS - 具有多个 jQuery 版本的 jQuery 插件 如果我找到一个解决方案,我会仔细查看并在此处发布一个解决方案。

4

2 回答 2

0

如果 jqWidgets 不支持开箱即用,我会试试这个:

  • 加载 jQuery
  • 加载 jqxWidget 3.3
  • 再次加载 jQuery,但在其 noConflict 模式下,并将其分配给$2例如(我不确定 RequireJS 是否可以这样做,但您可以复制 jQuery.js 文件并将其重命名为不同的名称以再次加载它)
  • 将第一个 jQuery 设置为 $1 ( window.$1 = $)
  • 将第二个 jQuery 设置为 $ ( window.$ = $2)
  • 加载 jqxWidget 3.6

现在每个 jqxWidget 都应该有自己独立的 jQuery。显然,两次加载 jQuery 并不理想,但除了在您的应用程序上使用更多内存之外,这应该不是问题。

于 2015-02-26T22:38:10.450 回答
0

您可以使用 requirejs 的“映射”功能,Map 允许您根据使用依赖的模块将相同的依赖映射到不同的文件。所以你像这样配置你的构建文件:

requirejs.config({
    paths: {
        "jquery": "vendor/jquery",
        "jqueryForjqx3.6": "toNoConflictJQueryModule",
        "jqx": "vendor/jqwidgets/3.3",
        "jqx3.6": "vendor/jqwidgets/3.6",
    ... other libs...
    },
    map:{
        '*':{
             .....
        },
        'jqx':{
            'jquery' : 'jquery'
        },
        'jqx3.6':{
             // map jquery to no conlict jquery
            'jquery' : 'jqueryForjqx3.6'
        },
        'jqueryForjqx3.6':{
            'jquery' : 'jquery'
        }
    },
    shim: {
        ... other shims ...
        // jqWidgets3.3
        "jqx/jqxcore": {
             deps: ["jquery"]
        },
        "jqx/<<some_plugin>>": {
             deps: ["jqx/jqxcore"],
             exports: "$.fn.<<some_plugin>>"
        },
        // jqWidgets3.6
        "jqx3.6/jqxcore": {
             deps: ["jquery"]
        },
        "jqx3.6/<<some_plugin>>": {
             deps: ["jqx3.6/jqxcore"],
             exports: "$.fn.<<some_plugin>>"
        },
    }
});

此配置根据使用它的模块将 jquery 依赖关系映射到不同的文件。

无冲突版本的内容可以是这样的:

define(['jquery'], function($){
    return $.noConflict();
});

您可以使用http://requirejs.org/docs/jquery.html#noconflictmap关于如何使用 jquery no-conflict 和 requirejs

于 2015-02-27T08:43:56.043 回答