我正在使用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月份对这个问题的回答是"你不能真正设置它是可选的" :
那不是我想要的。这是硬道理吗? : - /
似乎我可以通过安装jquery NPM软件包解决这个问题,这个软件包显然与DOM有关:
Can I use jQuery with Node.js?
我的理解是,如果我添加了这种依赖并且忽略它,我就没事了。我甚至可能会发现有一些很好的理由在服务器上进行DOM操作(我还没有想过要弄清楚为什么或如何有用,是吗?)
为了简单起见,我应该添加依赖项,而不是使用它?或者我可以进行装配,以便我只在服务器配置上提供jQuery null
,通过一些不会等待超时,错误和黑客的魔法?有人可以制作一个" jquery-null"包以某种方式回来并为jQuery提供{}
或null以平滑这样的情况?
建议表示赞赏! : - /
答案 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
}
});