【问题标题】:Defining global variable for Browserify为 Browserify 定义全局变量
【发布时间】:2016-06-16 16:43:59
【问题描述】:

我正在使用 SpineJS(它导出一个 commonjs 模块),它需要在全球范围内可用,因为我在任何地方都使用它,但似乎我必须对每个使用 Spine 的文件执行Spine = require('spine') 才能工作。

有没有办法定义一次Spine 以使其全球可用?

PS:我以 Spine 为例,但我一般想知道如何使用任何其他库来做到这一点。

【问题讨论】:

    标签: browserify spine.js


    【解决方案1】:

    在每个文件中写入Spine = require('spine') 是正确的做法。

    然而,使用globalwindow 对象有几种可能性(browserify 将global 对象设置为window,这是全局命名空间):

    • 在spine.js中:global.Spine = module.exports
    • 在 browserify 捆绑的任何其他 .js 文件中:global.Spine = require('spine')
    • 在脚本标签或.html文件引用的.js文件中,spine.js文件之后:window.Spine = require('spine')

    【讨论】:

    • 使用 jQuery 和 lodash/underscore 等常见依赖项,当您处理大型项目时,使用 require 样板文件将一半文件杂乱无章会变得很烦人。很高兴有其他选择
    • 这个想法是,这些文件中的每一个都是一个完全定义的单元,因此理论上您可以将它从一个项目中取出并放入另一个项目中,并且仍然很清楚它的依赖关系是什么并且 (有时)甚至在哪里可以找到它们。显然,如果您只想获得绝对最小的文件,您仍然可以解决这个问题,但将其视为文档而不是混乱本身会有所帮助。
    【解决方案2】:

    首先,对于您的示例,大卫是正确的。在您需要的每个模块中包含所有依赖项。它非常冗长,但没有任何编译时魔法可以缓解各种反模式和潜在的未来问题。

    真正的答案。

    这并不总是实用的。 Browserify 接受一个名为insertGlobalVars 的选项。在构建时,会扫描每个流文件以查找与提供的键名匹配的标识符,并将模块包装在 IIFE 中,其中包含解析模块中未分配的每个标识符的参数。这一切都发生在依赖关系树最终确定之前,这允许您使用 require 来解决依赖关系。

    TLDR

    在 Browserify 中使用 insertGlobalVars 选项。

    browserify({
      insertGlobalVars: {
        spine: function(file, dir) {
          return 'require("spine")';
        }
      }
    });
    

    对于每个扫描的文件,如果存在未分配的标识符spine,则解析为require("spine")

    【讨论】: