browserify-shim 在 var 范围内时不导出隐式全局变量

browserify-shim not exporting implicit globals when they are var scoped

根据 browserify-shim 文档,您可以通过在 package.json:

中使用以下语法来指定 browserify-shim 需要从遗留模块公开哪些全局变量
{
    "browserify-shim": {
        "legacyModule": "myVar"
    }
}

我希望可以通过 require('legacyModule')window.myVar 访问遗留模块。

根据我的经验,如果我尝试填充的非 commonjs 模块使用 window.myVar = x 或只是 myVar = x,则该模块将在全球范围内公开,并且可以通过 require() 按预期使用.

但是,当遗留模块使用 var myVar = x 时,这就是导致问题的原因,因为该模块只能通过 require('legacyModule') 而不是通过window.myVar.

browserify-shim documentation 指出:

Additionally, it handles the following real-world edge cases:

  • Modules that just declare a var foo = ... on the script level and assume it gets attached to the window object. Since the only way they will ever be run is in the global context — "ahem, ... NO?!"

正如@EvanDull 所建议的那样,我相信 browserify-shim 实际上可能并非设计为以这种方式工作,并且文档对此缺乏明确说明。在我进行的调试中,并没有出现 browserify-shim 被设计为 set 一个全局变量时 "handles" var foo = ...。在文档说它处理的地方,我相信这意味着它处理它还没有在全局对象上设置并且它仍然会为 CommonJS 导出该变量的值,例如var foo = ...; module.exports = foo;,这样就可以require()了。尽管您希望它做 var foo = ...; window.foo = module.exports = foo; 当然,因为它不会那样做并且 browserify 将遗留代码包装在一个函数中,所以 var foo 只创建一个局部变量。

您现在可以使用多种可能的解决方法:

  • 如果您不介意编辑遗留脚本,您只需删除 var 即可。

  • 您可以通过单独的 <script> 标签提取遗留脚本,而不是将它们捆绑在一起。

  • 您可以使用 browserify 转换将附加赋值 global.myVar = myVar 添加到遗留脚本的末尾。这将需要为您需要的每个特定脚本定制转换。

  • 您可以将捆绑包中的第一个文件制作成脚本,执行如下操作:

    [['legacyModule, 'myVar'], ...].forEach(function (mod) {
      window[mod[1]] = require(mod[0]);
    });