如何使用我自己的jQuery版本与浏览器模块

(我应该事先澄清一下:我的问题是关于Javascript中的闭包和客户端模块模式。它不是关于如何使用jQuery.noConflict()。)

我有一些人们可以添加到他们网站的Javascript。 我希望我自己的代码能够访问$变量,该变量解析为特定版本的jQuery,它与页面加载的内容无关。 如果我的所有代码都在一个文件中,在我定义的闭包内,这很容易。 但我正在努力找到一种干净的方法来使用模块模式来实现这一点,我的代码在单独的闭包中。

背景 (即明显的问题不是问题)

当我的所有代码都在一个文件中时,这很容易。 我可以在我最外层的闭包中创建一个$ var并使用$ .noConflict(…)来确保外部页面保留了自己的jQuery版本。 像这样的东西:

// This is easy and works as you'd expect (function() { var $; // The $ var in my local scope that the rest of my code can use. function loadMyVersionOfjQuery() { insertTheAppropriateScriptTagAndWaitForTheScriptToLoad(function() { // Set the $ in my local scope and restore the global jQuery. $ = jQuery.noConflict(true); } } loadMyVersionOfjQuery(); ... etc. ... })(); 

现在我正在使用browserify将我的代码分解成单独的文件,这已经不再那么容易了。 最麻烦的是我的jQuery版本是异步加载的。 所以当我的模块require()正在处理时,我的jQuery版本还没有准备好。 这使我无法在模块闭包的顶层创建和分配$ var。

我调查了一些想法

  1. 如果我可以将模块的初始化推迟到jQuery运行之后,那么我的每个模块都可以定义自己的$ var。 但这似乎不可能。 即使我试图在函数回调中隐藏它们,看起来我的require(…)调用也被积极遍历(browserify似乎实际上解析了JS以找到require语句)。
  2. 如果我可以定义一个动态代理对象,我可以用一个代理初始化我自己的$ vars,该代理稍后会委托给我加载的jQuery版本。 但是Javascript不支持动态代理模式。
  3. Browserify实际上定义了一个闭包,它将所有模块“转换”为单个文件时将其包装起来。 如果我能以某种方式给它一个代码片段插入这个闭包(简称“var $;”),我就会开展业务。 但我还没有找到任何办法。
  4. 作为最后的手段,我想到我可以在browserify输出周围创建自己的闭包,并在那里定义我需要的范围变量。 通过处理输出文件或者通过围绕browserify内容对几个简单文件进行hacky连接(类似“(function(){var $;”+ bundle.js +“})();”。但这是太讨厌了。

有没有人有任何想法? 如何在多个文件中开发客户端Javascript模块,但仍然可以一起关闭所有代码?

可能是我是唯一一个遇到这种情况的人(Browserify +我想在所有模块中使用的异步加载的库),但我会分享我刚刚提出的解决方法案件…

我最终定义了一个异步加载jQuery的模块,然后在它准备好时通知监听器。 它基本上是对异步“需求”的非常简单的支持。 我想要使​​用jQuery的所有模块最终都会得到一些像这样的样板代码:

 var $; require('./jquery-provider').onLoad(function(jQuery) { $=jQuery; }); 

它并不完美,但很简单。 它的工作原理是因为我的库的入口点启动了我的’jQuery提供程序’并在它调用我所有其他模块之前等待一个准备好的回调。 因此,虽然我的模块都得到了Browserify的积极执行,因为它解决了所有的依赖关系,但我的模块中的所有函数都没有运行,直到我所需的库可用并且已传递给它们。

(如果此模式对其他人有用,我可以共享更多代码。)

在我的app.js中我有这个

 var $ = require('jquery')(window); global.jQuery = require("jquery"); 

然后使用从npm“plugin”下载并导入de模块并执行,就像这样。

 var plugin = require('plugin'); plugin(); 

并且工作正常。