Javascript 是否有方法允许browserify模块访问全局范围(窗口对象)?

Javascript 是否有方法允许browserify模块访问全局范围(窗口对象)?,javascript,node.js,browserify,commonjs,Javascript,Node.js,Browserify,Commonjs,场景 我正在使用Browserify(或类似导入的NodeJS/CommonJS)来要求一些JavaScript库。然而,我很难让他们玩得很好,因为显然Browserify默认拒绝对所有模块的全局范围访问。例如,这样做不起作用 file1.js require('moment'); moment(new Date()); // throws moment is undefined file2.js require('moment'); moment(new Date()); // thro

场景

我正在使用Browserify(或类似导入的NodeJS/CommonJS)来要求一些JavaScript库。然而,我很难让他们玩得很好,因为显然Browserify默认拒绝对所有模块的全局范围访问。例如,这样做不起作用

file1.js

require('moment');
moment(new Date()); // throws moment is undefined
file2.js

require('moment');
moment(new Date()); // throws moment is undefined
但这是通过将file1.js的内容更改为以下内容来实现的:

window.moment = require('moment');
window.moment = require('moment');
require('./../../node_modules/moment-timezone/builds/moment-timezone-with-data-2010-2020'); // the location of my moment-timezone library

问题

到目前为止,这已经足够好了,但是现在我在加载MomentTimeZone库(MomentJS的扩展)时遇到了问题。Timezone的文档暗示这两个脚本应该在窗口全局范围内运行,方法是将它们添加为脚本标记,如下所示

<script src="moment.js"></script>
<script src="moment-timezone-with-data.js"></script>
然而,这似乎很难实现,因为如果我尝试以下方法

window.moment = require('moment');
window.moment = require('moment');
require('./../../node_modules/moment-timezone/builds/moment-timezone-with-data-2010-2020'); // the location of my moment-timezone library
我得到一个运行时错误,说
moment.tz未定义(这意味着第二个库没有使用全局作用域运行)。如果我尝试将
窗口.moment
添加到第二行代码中,我将重写完整库的第一个实例

简而言之,是这样

是否有一种方法允许某些Browserify导入具有全局作用域访问权限,或以
窗口
对象作为其作用域运行


我知道这会带来安全隐患,但有选择地使用,这将非常有用,同时需要像JavaScript库这样需要全局访问才能正确设置自己的东西。任何帮助都将不胜感激。

将微型库放入vendor.js,将其包含在页面上的
,使用
browserify shim
将其告知
browserify
,并将其与模块中的
require('libname')
一起使用

更大的库可以包括在供应商CDN中,也可以通过browserify shim进行browserify

index.html


打开devtools并检查输出
package.json

{
“脚本”:{
“构建”:“cat vendor1.js vendor2.js>dist/vendor.js&&cp index.html dist/index.html&&browserify index.js-o dist/bundle.js”
},
“browserify垫片”:{
“供应商1”:“全球:供应商1”,
“vendor2”:“全局:vendor2”
},
“浏览化”:{
“变换”:[“browserify shim”]
},
“依赖性”:{
“浏览化”:“^14.1.0”,
“浏览垫片”:“^3.8.14”
},
“依赖项”:{
“时刻”:“^2.18.1”,
“时刻时区”:“^0.5.11”
}
}
关于上述
package.json
,需要注意的几点:

  • 构建:它在dist文件夹中构建“应用程序”,创建以下结构:
    • 距离
      • index.html
      • bundle.js
      • vendor.js
  • “browserify”条目:它只是添加browserify垫片
  • “browserify shim”条目:它告诉browserify,
    vendor1
    vendor2
    作为窗口(全局)对象的属性可用。Browserify不会尝试绑定它们,而
    require()
    只会返回这些属性。您需要确保它们实际可用(因此上面的
    index.html
    将它们与
index.js

require('moment');
moment(new Date()); // throws moment is undefined
var momentfromnpm=require('moment-timezone');
var vendor1=需要('vendor1');
var vendor2=需要('vendor2');
console.log(“你好”);
log(“使用来自npm的模块”,momentfromnpm().tz(“Europe/London”).format());
log(“使用vendor1.js(捆绑到vendor.js中)中的函数)”,vendor1();
log(“使用来自vendor2.js(绑定到vendor.js)的‘模块’”,vendor2.doWork();
vendor1.js

require('moment');
moment(new Date()); // throws moment is undefined
window.vendor1=function(){//`
return“我是一个简单的函数,定义在窗口上”;
};
vendor2.js

require('moment');
moment(new Date()); // throws moment is undefined
var vendor2={//也可以是window.vendor2
doWork:function(){
console.log(“供应商2正在工作”);
}
};

按照上的说明安装
时刻时区
软件包

file1.js中,将
window.moment
定义为:

window.moment = require('moment-timezone/builds/moment-timezone-with-data-2010-2020');

这应该允许您在file2.js

中使用
moment().tz()然后将它们提供给使用browserify处理的模块,我们已经导入了带有脚本标记的较重的库。但是,我们更喜欢将较小的库捆绑到vendor.min.js文件中,因为对于高速互联网用户,等待1-4kb库的服务器响应通常要比下载它花费更长的时间。这并不妨碍禁止您填充这些库。因此,您将微小的库放入vendor.js中,并将其包含在您的页面上,使用browserify shim使它们为人所知,并将它们与require('libname')一起使用在你的模块中。@weirdan,你能举一个例子吗?我会试着把它拼凑起来作为答案。顺便说一句,对于moment lib来说,它不是真正需要的,因为你只需要用npm安装
moment timezone
,然后像这样使用它:
var moment=require('moment-timezone'));
-这将为您提供一个带有时区支持和tz数据加载的增强力矩模块。
require('moment');
moment(new Date()); // throws moment is undefined