javascript - Node.JS 和浏览器之间的 RequireJS 对 jQuery 的简单可选依赖

标签 javascript jquery node.js module requirejs

我正在使用 RequireJS,并尝试将 jQuery 小部件打包到一个文件中以便于使用。小部件的 JavaScript 代码内部有一定数量的非 UI 函数,这些函数不会调用 $ 任何内容,我希望将其导出并能够在服务器端使用。

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

我希望小部件的唯一依赖项是 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;        
}

阅读其他人的问题后,我注意到一月份对这个问题的回答“你不能真正将其设置为可选”:

requireJS optional dependency

这不是我想要的。这是最后一句话吗? :-/

看来我可以通过安装 jquery NPM 包来解决这个问题,它显然以某种方式处理 DOM:

Can I use jQuery with Node.js?

我的理解是,如果我添加此依赖项并忽略它,我会没事的。我什至可能会发现在服务器上进行 DOM 操作有一些充分的理由(我还没有思考足够多的问题来弄清楚为什么或如何有用,是吗?)

那么为了简单起见,我应该添加依赖项而不使用它吗?或者我可以通过一些不涉及等待超时、错误和黑客的魔法来将其配置为在服务器配置上提供 null 的 jQuery?有人可以制作一个“jquery-null”包,它以某种方式返回并为您提供一个 {} 或 null 供 jQuery 来平滑这样的情况吗?

感谢建议! :-/

最佳答案

您提到的答案是“您无法真正将其设置为可选”,然后给出了即使在没有模块的情况下也可以运行的解决方案。您可以使用errback如果运行服务器端,则不会执行任何操作。

以下代码假定 RequireJS 的 require 调用可用作 requirejs。在浏览器中加载 RequireJS 时,这是默认设置(即加载 RequireJS requirejs === require 后为 true。)在服务器端,您必须通过以下方式使其可用:

if (typeof window === "undefined")
    var requirejs = require('requirejs');

(如果 Node 中存在全局设置 window 的内容,上面的代码显然会失败。我从未遇到过这个问题。)

一旦解决了上述问题,我们就可以:

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;        
});

您提到的答案和 RequireJS 的文档(我在上面链接)提到检查失败模块的 id 并取消定义它。我非常确定您不需要取消定义它,因为您不会尝试从不同的位置再次加载它。如果有一天 jQuery 依赖于其他东西,检查模块 id 将是一种让你的代码面向 future 的方法。现在,加载 jQuery 只是加载 jQuery,因此如果出现故障,则不能是 jQuery 以外的任何其他模块。

我不会包含 jQuery 服务器端的实际代码,除非我有真正的充分理由。如果我想摆脱 errback,无论出于什么原因,我会做的就是构建一个包含假 jQuery 模块的服务器端使用代码。像这样的东西:

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

然后测试它:

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

如果您最终需要 jQuery 服务器端,您还必须安装 jsdom 之类的东西。过去,使用 npm install jquery 安装 jQuery 会在安装中包含 jsdom,但我认为这种情况最近发生了变化。

关于javascript - Node.JS 和浏览器之间的 RequireJS 对 jQuery 的简单可选依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22471822/

相关文章:

javascript - 无法在Vue中设置下拉列表中的默认选定项

javascript - 使用复选框作为按钮来自动计算 jquery 中的总数?

javascript - 文件创建后生成 HTML 链接

jquery - 使用 row-eq-height 的 Bootstrap 等列高度不适用于我的页面

node.js - NextJS在next.config.js文件中定义后重定向不重定向url

javascript - Monaco 编辑器 - 与 JSHint 集成

javascript - 如何在 SVG 图像之间切换

javascript - 如何检查和测试 JavaScript 应用程序泄漏了多少内存

javascript - 如何从网站服务器端获取文本

javascript - 将 Axios.all 用于 for 循环中的一组 post 调用