(我应该预先澄清:我的问题是关于 Javascript 中的闭包和客户端模块模式。这不是关于如何使用 jQuery.noConflict()。)
我有一些 Javascript,人们可以将其添加到他们的网站中。我希望我自己的代码能够访问 $ 变量,该变量解析为独立于页面加载的特定版本的 jQuery。如果我的所有代码都在一个文件中,在我定义的闭包内,这很容易。但我正在努力寻找一种干净的方法来使用模块模式来执行此操作,其中我的代码位于单独的闭包中。
背景(即显而易见的事情isn't问题)
当我的所有代码都在一个文件中时,这很容易。我可以在最外面的闭包中创建一个 $ 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。
我研究过的一些想法
- 如果我可以将模块的初始化推迟到 jQuery 运行之后,那么我的每个模块都可以定义自己的 $ var。但这似乎不可能。看起来我的 require(...) 调用被积极地遍历,即使我试图将它们隐藏在函数回调中(browserify 似乎实际上解析了 JS 以找到 require 语句)。
- 如果我可以定义一个动态代理对象,我可以使用代理初始化我自己的 $ vars,该代理稍后将委托给我加载的 jQuery 版本。但Javascript不支持动态代理模式。
- Browserify 实际上定义了一个闭包,当我的所有模块“转换”为单个文件时,它将对其进行包装。如果我能以某种方式给它一段代码插入到这个闭包中(简单地“var $;”),我就可以做生意了。但我还没有找到任何方法来做到这一点。
- 作为最后的手段,我想到我可以围绕 browserify 输出创建自己的闭包,并在那里定义我需要的作用域变量。通过处理输出文件或通过对 browserify 内容进行几个简单文件的巧妙串联(类似于“(function(){var $;”+bundle.js +“})();”。但这是太老套了。
有人有什么想法吗?如何在多个文件中开发客户端 Javascript 模块,但仍能将所有代码一起关闭?
可能我是唯一遇到这种情况的人(Browserify + 我想在所有模块中使用的异步加载库),但我将分享我刚刚提出的解决方法案件...
我最终定义了一个模块,该模块异步加载 jQuery,然后在准备就绪时通知侦听器。它基本上是对异步“需求”的非常简单的支持。我所有想要使用 jQuery 的模块最终都会有一小段样板代码,如下所示:
var $; require('./jquery-provider').onLoad(function(jQuery) { $=jQuery; });
它并不完美,但很简单。它之所以有效,是因为我的库的入口点启动了我的“jQuery 提供程序”,并在调用我的所有其他模块之前等待准备好的回调。因此,尽管我的模块在解决所有依赖关系时都被 Browserify 积极执行,但在我所需的库可用并传递给它们之前,模块内的任何函数都不会运行。
(如果这个模式对其他人有用,我可以分享更多代码。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)