Browserify:从脚本访问dom元素?

时间:2013-10-20 19:13:41

标签: javascript requirejs browserify

我有一个javascript库,可以在客户端站点中使用,如下所示:

  <script src="foo.js"></script>
  <div id="mydiv"></div>
  <script>
    (function() {
        foo(document.getElementById("mydiv");
    })();
  </script>

即。 foo.js导出一个函数(“foo”),假设将DOM元素作为参数。

我想将foo.js分成几个不同的“模块”(逻辑部分),我正在查看BroserifyrequireJS。 问题是如果browserify(并且据我所见,requireJS)不导出任何foo的顶级函数,那么我无法从html文件访问“foo”函数,如上所示。 似乎使用browserify我可以在构建最终的js时使用 -r 选项:

browserify -r ./foo.js > bundle.js 

这将创建可在客户端站点中使用的全局 require 。我对这个解决方案不是很满意,因为它污染了全局空间,我的脚本意味着嵌入其他网站(可能会发生冲突要求)。 我在这里运气不好吗?我错过了什么吗? 我想我只需要一种方法来加入不同的js源文件,以便于开发并只导入一个最终的javascript。有没有更适合我需求的解决方案?

米;

1 个答案:

答案 0 :(得分:1)

如果将脚本拆分为多个文件,则这些文件需要能够相互通信。两个不同脚本文件相互通信的唯一方法是通过全局命名空间,这是他们唯一的共同点。

我不熟悉Broserify,但在requirejs的情况下,脚本利用全局命名空间进行通信的方式是,当它们执行时,它们都将对自身的引用传递给全局“require”或全局“define”函数。 requirejs本身然后在内部跟踪脚本,这样他们就不必对全局命名空间产生任何其他影响 - 但是必须通过创建名称“require”和“define”来实现。

在任何情况下,您的脚本总是可以通过分配一个未声明的变量来影响全局命名空间,该变量将在全局对象中创建一个属性:

foo = function() {}; // creates global name as long as no other 'foo' is in scope
// or
window.foo = function() {}; // as long as no other 'window' variable is in scope

无论您的脚本如何加载,您都可以随时执行此操作。其他脚本现在可以通过读取和/或分配此全局名称的属性,通过全局名称'foo'进行交互。

foo.prop1 = 'val1';
if(foo.preExistingProp) {
    // do something
}

像requirejs这样的库的主要目的是,在开发脚本时,相关依赖关系可能会发生变化。您可以想象脚本A需要脚本B和C,脚本B需要脚本D.现在有多个脚本可以有效加载的命令。一些是:

D -> B -> C -> A
C -> D -> B -> A
D -> C -> B -> A

requirejs采用依赖并将其转换为线性加载顺序。随着此树的更改,它会重新计算加载顺序以确保它保持有效。

如果您需要这种功能,我鼓励您使用这样的库,尽管您对全局名称空间的关注是合适的。如果您只需要一个自己管理的简单线性加载顺序,那么您可以让脚本直接与全局'foo'名称进行交互,如上所述。