如何将 Browserify 与外部依赖项一起使用?

IT技术 javascript jquery performance integration browserify
2021-03-17 19:47:15

我正在尝试将 Browserify 慢慢引入我的网站,但我不想重写所有的 js,也不想将重复的 jquery 实例和其他库与我的 Browserify 构建捆绑在一起。

如果我构建我的module,将 jquery 列为外部依赖项,那么我如何将它指向我的全局 jquery 实例?另一个目标是消除 mylibs 全局(下面的示例),所以我不想在我的module中使用它。

这就是我想要做的(伪代码)。这将在我网站的回购中 - 而不是module的。该module将与 Bower 一起安装:

var mylibs.jQuery = $.noConflict(); // global used by lots of existing code
module.exports = {
    jquery: mylibs.jQuery // can be imported by my module as require('jquery')
};

我正在努力实现这样的目标。这可能吗?

3个回答

您可以通过使用browserify-shim来实现假设您有一个名为的modulemymodule.js该module在全局范围内依赖于 jQuery,其内容如下:

var $ = require('jQuery');

console.log(typeof $);
  1. 安装 browserify-shim:

    npm install browserify-shim --save-dev
    
  2. 在 package.json 文件中,告诉 browserify 使用 browserify-shim 作为转换:

    {
        "browserify": {
            "transform": [ "browserify-shim" ]
        }
    }
    
  3. 在 package.json 文件中,告诉 browserify-shim 将 jQuery 映射到全局范围内的 jQuery:

    {
        "browserify-shim": {
            "jQuery": "global:jQuery"
        }
    }
    
  4. 运行浏览器

    browserify mymodule.js > bundle.js
    

如果您检查 bundle.js,您会注意到它require('jQuery')被替换为(window.jQuery).

AFAIK jQuery 在最新版本中支持 CommonJS。
2021-04-21 19:47:15
这 (browserify-shim) 不适用于传递性要求,因为它要求 (!) [offending] module还包含适当的 package.json 配置 - 当所述module是外部的时很难做到。
2021-04-30 19:47:15
@jgillich 如果您同时需要 jquery 作为module(因为您自己的代码)和全局(因为 npm 之外的第三方插件),那么这没有用。垫片解决了这个问题。
2021-05-09 19:47:15
如果在多个文件中使用,我们如何做到这一点?
2021-05-17 19:47:15

Browserify-shim 不能跨节点module传递:它可用于正确填充顶级(在您自己的 package.json 中)module,但它不能填充其他 npm 包中的module(使用它们自己的 package.json 文件)。

在处理依赖于 jQuery module的节点module(例如,具有对等依赖性的插件)时,这很尴尬,但 jQuery 库应该仍然是外部的。

我的解决方案 - 在概念上类似于伪代码 - 是在 browserify 本身的帮助下创建一个自定义的“预加载垫片”。

  1. jquery从 的生成中排除modulebundle.js,否则正常构建包。

    安装适当的 node/npm module以满足构建要求。要排除的“外部”module将不会包含在包中,但需要满足编译依赖项解析。

     browserify -x jquery .. > dist/bundle.js
    
  2. 创建一个名为 jquery.js 的文件并包含以下内容:

     module.exports = window.jQuery; // or whatever
    
  3. 生成shim.js包括刚刚上一个文件。

     browserify -r jquery.js > dist/shim.js
    

    然后编辑文件以使用 jQuery 作为module名称。

  4. 在浏览器中,加载 jquery(外部依赖)、shim.js,然后bundle.js

    当包文件尝试加载 jquery module(它没有定义)时,它将回退到 shim 文件中定义的module(以前)并运行自定义代码。在这种情况下,这是通过先前定义的全局管道。

    或者:什么 browserify-shim "global:" 试图做,实际上只是 .. 全局。


直接使用 browserify module - 而不是 grunt,我越来越讨厌它 - 可能会产生一个“更精致”的解决方案。

@dmarr 我还没有找到更好的方法。
2021-04-26 19:47:15
嘿@user2864740,我想知道你是否想出了更优雅的解决方案来解决这个问题?我试图开始做你所做的“在其他 npm 包中填充module”,这感觉就像我找到的最接近解释解决方案的事情。
2021-05-16 19:47:15
需要注意的是Browserify允许与被给予沿module/目标名称-r选项,可避免垫片文件,以便手动编辑:browserify -r ./jquery.js:jQuery > dist/shim.js-r如有必要,还可以提供多个选项以将多个module捆绑到同一个文件中。
2021-05-19 19:47:15

这可以通过 1-liner 来完成:

echo "module.exports=window.jQuery" > node_modules/jquery.js

为每个外部依赖项在构建脚本中添加 1 行。无需将任何特殊选项传递给 Browserify。

你能多说一点吗?我将我的存储库克隆到我的生产服务器进行部署。从来没有遇到过这样的问题——我相信你在引用一个有效的问题,我希望你能把它充实一点。
2021-04-24 19:47:15
@Lightbulb - node_modules 不需要受源代码控制。构建脚本大致如下:echo "module.ex..." > node_modules/... && browserify .... 即,node_modules 是作为构建的一部分准备的;在有人克隆 repo 后,它没有准备就绪的危险。如果他们想建造,npm install无论如何他们都必须先做。帮我看看我错过了什么。
2021-04-28 19:47:15
脆弱的黑客。工作直到以某种方式克隆回购。
2021-05-07 19:47:15
我假设这是基于 node_modules 通常不在您的源代码管理中的事实。这可以在 git 中通过像这样设置你的忽略来解决: node_modules/* newline !node_modules/jquery.js 我认为他是对的,虽然有点讨厌,但是嘿,我认为这个问题的所有解决方案都有点黑客。这实际上是一个非常简单的,不依赖于任何其他节点module,如 browserify-shim。
2021-05-10 19:47:15