在Node.JS和浏览器之间轻松可选地依赖于jQuery for RequireJS

时间:2014-03-18 06:25:55

标签: javascript jquery node.js module requirejs

我正在使用RequireJS,并尝试打包一个jQuery小部件,以便在一个文件中使用。在小部件的JavaScript代码中有一定数量的非UI功能,不会调用$ - 任何我想要导出并能够在服务器上使用的功能侧。

(不依赖于jQuery的共享例程曾经位于一个名为client-server-common.js的独立模块中。但就像我说的那样,我希望减少数量文件...并且没有真正的理由可以将服务器上的小部件的死代码包括在内。因此小部件可以包含公共代码。)

我希望我的唯一依赖项是jQuery和下划线,jQuery可选(在这种情况下它会降级为client-server-common.js)。所以我正在寻找的界面就像:

require(['jquery', 'underscore'], function ($, _) {
    var exports = {...};

    if ($) {
        // Do the stuff that only makes sense in the client
        // Totally fine if there is no jquery; in that case
        // all we probably care about are the exports
        ...
    }

    // Do the stuff for both client and server
    ...

    // Return the exported functions
    return exports;        
}

阅读其他人提出的问题,我注意到1月份对这个问题的回答是"你不能真正设置它是可选的"

requireJS optional dependency

那不是我想要的。这是硬道理吗? : - /

似乎我可以通过安装jquery NPM软件包解决这个问题,这个软件包显然与DOM有关:

Can I use jQuery with Node.js?

我的理解是,如果我添加了这种依赖并且忽略它,我就没事了。我甚至可能会发现有一些很好的理由在服务器上进行DOM操作(我还没有想过要弄清楚为什么或如何有用,是吗?)

为了简单起见,我应该添加依赖项,而不是使用它?或者我可以进行装配,以便我只在服务器配置上提供jQuery null,通过一些不会等待超时,错误和黑客的魔法?有人可以制作一个" jquery-null"包以某种方式回来并为jQuery提供{}或null以平滑这样的情况?

建议表示赞赏! : - /

2 个答案:

答案 0 :(得分:1)

你提到的答案是"你不能真正设置它是可选的"然后提供即使在没有模块的情况下也能运行的解决方案。您可以使用errback,如果在服务器端运行则不会执行任何操作。

以下代码假定RequireJS' require来电requirejs来电requirejs === require。在浏览器中加载RequireJS时,这是默认设置(即,在加载RequireJS if (typeof window === "undefined") var requirejs = require('requirejs'); 之后为真。)在服务器端,您必须使用以下内容使其可用:

window

(如果Node中存在全局设置requirejs(['underscore'], function (_) { var exports = {...}; requirejs(['jquery'], function ($) { // This will execute only if jquery is present. // Do the stuff that only makes sense in the client // Totally fine if there is no jquery; in that case // all we probably care about are the exports ... }, function (err) { // This will execute if there is an error. // If server-side, do nothing. If client-side, scream! }); // Do the stuff for both client and server ... // Return the exported functions return exports; }); 的内容,上述代码显然会失败。我从未遇到过这个问题。)

一旦完成以上操作我们就可以做到:

define(function() {
    return "I'm totally fake";
});

你提到的答案和RequireJS'文档(我上面链接)提到检查失败模块的ID并取消定义它。我非常肯定您不需要取消定义它,因为您不会尝试从其他地方再次加载它。如果有一天jQuery依赖于其他一些东西,检查模块ID将是一种未来证明代码的方法。现在,加载jQuery只是加载jQuery,所以如果出现故障,它不能是除了jQuery之外的任何其他模块。

我不会包含jQuery服务器端的实际代码,除非我有实际的实际原因。如果我想摆脱错误,无论出于什么原因,我会做的是为服务器端使用包含假jQuery模块的代码构建。类似的东西:

requirejs(['jquery'], function ($) {
    if ($ !== "I'm totally fake") {
        // Do the real deal.
    }
});

然后测试一下:

npm install jquery

如果你最终需要jQuery服务器端,你还必须安装像jsdom这样的东西。以前安装jQuery {{1}}会在安装中包含jsdom,但我认为最近已经改变了。

答案 1 :(得分:-1)

  

我正在使用RequireJS,并尝试打包一个jQuery小部件,以便在一个文件中使用。 [...]我喜欢我对widget的唯一依赖是jQuery和下划线,jQuery是可选的[..]阅读其他人的问题,我注意到1月份这个问题的答案说&#34 ;你不能真正设置它是可选的" [..]那不是我想要的。这是硬道理吗? : - /

不,这不是最后一句话

这实际上可以优雅而简单地完成。我已经描述过如何在my answer中加载 ,但我会在此重复它的要点:

define(['require'], function(require){
  if (require.defined('jquery') {
    var $ = require('jquery');
    $.fn.something = function(){};
  }
});

我们不会直接添加相关性,而是仅在已定义时手动要求,因此我们不会触发任何请求。

我们声明对require的依赖关系,然后在我们的模块中使用它实际上是recommended by the RequireJS author,但我的实验表明这实际上也有效:

define(require.defined('jquery') ? ['jquery'] : [], function($){
    if ($) {
        // Yippee, all jQuery awesomeness is available
    } 
});