Javascript 是否有方法允许browserify模块访问全局范围(窗口对象)?
场景 我正在使用Browserify(或类似导入的NodeJS/CommonJS)来要求一些JavaScript库。然而,我很难让他们玩得很好,因为显然Browserify默认拒绝对所有模块的全局范围访问。例如,这样做不起作用 file1.jsJavascript 是否有方法允许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
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