使用带有 RequireJS 的私有 jquery - 优化后的问题

Posted

技术标签:

【中文标题】使用带有 RequireJS 的私有 jquery - 优化后的问题【英文标题】:Using private jquery with RequireJS - issue after optimisation 【发布时间】:2013-07-11 00:52:17 【问题描述】:

我正在使用 requireJS 和 jQuery 的 CDN 版本(现在是推荐的方法)组合一个框架,并且在优化代码时遇到了一些问题。输出是命名空间的,我指定每个模块使用文档中概述的私有版本的 jquery:

require.config(
    // Add this map config in addition to any baseUrl or
    // paths config you may already have in the project.
    map: 
      // '*' means all modules will get 'jquery-private'
      // for their 'jquery' dependency.
      '*':  'jquery': 'jquery-private' ,

      // 'jquery-private' wants the real jQuery module
      // though. If this line was not here, there would
      // be an unresolvable cyclic dependency.
      'jquery-private':  'jquery': 'jquery' 
    
);

// and the 'jquery-private' module, in the
// jquery-private.js file:
define(['jquery'], function (jq) 
    return jq.noConflict( true );
);

优化后我看到的问题是“jquery-private.js”文件中未定义“jq”。

有什么想法吗?我试过设置 jq = $ 但这似乎破坏了全局。

谢谢。

【问题讨论】:

如果你把地图配置拿走,不尝试使其成为私人版本,它可以正常工作吗? 是的,没有地图配置也能正常工作 【参考方案1】:

为了让它工作,我改变了我使用 Require 的方式(可能我应该一直这样做)。这些信息可能对其他人有用,所以我想我会把它放在那里。

之前我在定义的模块中指定了任何依赖项:

define( [ "dep1", "dep2", "jquery" ], function( var1, var2, jq ) 

这最初工作得很好,但在优化时失败了。我将依赖项移至包含此模块的 require 函数调用,然后它开始在优化前后都可以正常工作,并且私下使用 jquery:

require( [ 'jquery', 'dep1', 'dep2' ], function( jq, var1, var2 ) 
    formValidator.formValidationInit( jq( el ) );
);

我不认为这会有所作为,但似乎也是如此。

还值得注意的是,我不得不更改 jquery-private 文件,因为它仍然引发有关“jq”未定义的问题。我现在将 jq 设置为等于全局 $ 并返回它以便可以私人使用:

define(['jquery'], function () 
    var jq = $;
    return jq.noConflict( true );
);

【讨论】:

这是绝对错误的使用 requireJS 的方式。您所做的只是声明一个 require 加载,而不是定义一个模块——还不如不使用 requirejs。 'jq' 未定义可能是因为您在配置的路径中缺少 'jquery' 属性(请参阅 explunit 的答案)。 requireJS 文档中缺少这条重要信息。 谢谢罗伯特-感觉不对,但是我在编译代码和使用私有 jquery 时遇到了问题。读完这篇文章后,我回去重构了我的代码,它按预期工作。本质上,我将模块从 require 调用中移回模块定义中。虽然在我最初的帖子中丢失了,但我确实列出了 jquery 路径,但也看到文档中缺少这个琐碎的信息。再次感谢您的回复【参考方案2】:

这是我为使RequireJS jQuery Instructions page 链接的jQuery CDN & optimization sample 与您在原始问题中粘贴的Mapping Modules to use noConflict 部分一起使用所做的操作。

1 - 分叉sample

2 - 使用此内容创建文件 www/js/lib/jquery-private.js

define(['jquery'], function (jq) 
    return jq.noConflict( true );
);

3 - 修改 www/js/app.js 以粘贴 map 部分,因此 require.config 现在看起来像这样:

requirejs.config(
    "baseUrl": "js/lib",
    "paths": 
      "app": "../app",
      "jquery": "//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min"
    ,
    map: 
      '*':  'jquery': 'jquery-private' ,
      'jquery-private':  'jquery': 'jquery' 
        
);

4 - 修改 www/js/app/main.js 以使用 jqlocal 而不是 $(只是为了向自己证明它不是全局 jQuery:

define(["jquery", "jquery.alpha", "jquery.beta"], function(jqlocal) 
    jqlocal(function() 
        jqlocal('body').alpha().beta();
    );
);

5 - 更改为tools 文件夹并运行:

node r.js -o build.js

6 - 更改为创建并运行 servedirwww-build 文件夹(与什么 Web 服务器无关,但这就是我用于开发的)

7 - 浏览到应用程序的本地地址和端口号(在我的情况下为 http://localhost:8000/app.html)并看到:

Alpha 是围棋!

测试版开始了!

你可以看到最终结果here

【讨论】:

如果不是很明显,'jquery' 的路径值在 RequireJS 文档中是至关重要的。我自己碰到了这个,用头撞墙大约半个小时。如果不存在,jq 将在 jquery-private.js 模块中未定义。

以上是关于使用带有 RequireJS 的私有 jquery - 优化后的问题的主要内容,如果未能解决你的问题,请参考以下文章

在 ES5 中使用带有 TypeScript 和 RequireJs 的 Knockout 类型

带有requirejs的骨干 - 传递给视图时“模型未定义”

使用requireJS的shim参数 解决插件 jquery.ui 等插件问题

如何使用 jQuery、RequireJS 和 KnockoutJS 创建基本的 TypeScript 项目

RequireJS库的定义说明

骨干 1.1.2,木偶,requirejs,最小版本