Browserify:如果需要,使用 module.exports,否则暴露全局变量

41

我在考虑为我的一些项目采用 Browserify,但是希望确保其他人不必使用 Browserify 就可以使用(打包的)代码。显而易见的方法是通过 module.exportswindow. 全局同时公开模块导出。然而,我不想为那些正在 require 脚本的人污染全局命名空间。

是否有可能检测到脚本是否正在被 require?如果可以的话,我可以做如下操作:

var mymodule = (function() { ... })();
if (isRequired()) {
  module.exports = mymodule;
} else {
  window.mymodule = mymodule;
}
请注意,无论如何,都将预先捆绑此模块,因此var mymodule不会暴露全局变量。另外,目前我正在使用揭示模块模式,但愿意切换到适用于browserify的其他模式。

如何使模块既可require,又可以通过<script src=加载?最好的方法是在这两种情况下都暴露一个全局变量吗?

4个回答

45

2
链接使用了已弃用的代码。无法再将选项传递给bundle()。此外,该链接没有解释beep-boop是从哪里来的,名称是否重要,以及在现实世界中应该用什么替换它。 - Trevor
2
我不确定正确的术语,但在这个例子中,“beep-boop”是您想要包含独立函数的“命名空间”。因此,如果我使用browserify infile --standalone myspace -o outfile将函数byteLength(...){...} browserify化,我将通过从已经通过require()包含outfile的JS文件内调用myspace.byteLength(...)来访问该函数。 - parttimeturtle
1
只是为了澄清一下:使用browserify版本17.0.0,上述操作可以给我提供工作捆绑包,并正确地公开了一个驼峰式全局变量“beepBoop”。 - KellyCode

21

我正在处理一个构建库的相同问题,以下是我的初步意见。我认为我们需要将图书馆的受众分为几类:

  1. 那些使用browserify和NPM的人
  2. 那些只下载mylib.min.js并以某种方式使用的人
  3. 可能是第三类——使用AMD(带有bower?)的人

因此,对于1来说很容易,您将拥有一个index.js模块:

module.exports = function () { /* code */ }

你的package.json文件将会有一个主要入口:

"main": "index.js"

请注意,我没有在index.js中添加任何window.xx代码。

对于第二点,我认为最好的办法是创建一个standalone.js文件。

var mylib = require('./index.js');
global.window.mylib = mylib;

这是 Browserify 应该构建的内容。

如果您关心 3,您可以按以下方式调整 standalone.js:

var mylib = require('./index.js');
if (typeof global.window.define == 'function' && global.window.define.amd) {
  global.window.define('mylib', function () { return mylib; });
} else {
  global.window.mylib = mylib;
}

2
“global”不就是“window”吗?如果是这样,那么应该是“global.mylib = mylib”,而不是“global.window.mylib = ...”吧? - Duncan

2

假定另一个库没有创建全局的 module.exports 对象,您可以简单地检查 module.exports 是否存在。

var mymodule = (function() { ... })();
if (module && module.exports) {
  module.exports = mymodule;
} else {
  window.mymodule = mymodule;
}

Browserify 使 modulemodule.exportsrequire 在所有捆绑的文件中可用。因此,只需进行捆绑即可使用它们。感谢您的回复。 - Bryan Head

0
为什么不用一个闭包将整个东西包起来,并将exports作为参数传递呢?
(function (exports) {
    // code here
    // ...
    exports.foo = bar;
})(exports || this);

这样它也会导出到WebWorker范围和其他“无窗口”的环境中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接