有没有办法让browserify模块访问全局范围(窗口对象)?
情景
我使用Browserify(或像导入NodeJS / CommonJS)需要一些JavaScript库。 然而,我很难让他们玩的很好,因为默认情况下显然Browserify拒绝全局范围访问所有模块。 例如,这样做不起作用;
file1.js
require('moment');
file2.js
moment(new Date()); // throws moment is undefined
但是,这通过将file1.js的内容更改为以下内容来工作。
window.moment = require('moment');
问题
到目前为止,这已经运行得很好,但是现在我无法加载时区库(MomentJS的扩展)。 Moment Timezone的文档意味着这两个脚本都应该在窗口全局范围上运行,将它们添加为脚本标签,
<script src="moment.js"></script> <script src="moment-timezone-with-data.js"></script>
所以他们可以这样使用;
moment().tz("America/Los_Angeles").format();
然而,这似乎很难实现,因为如果我尝试以下;
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 is undefined
(意味着第二个库没有与全局范围运行)。 如果我尝试将window.moment
添加到第二行代码,我将重写完整库的第一个实例。
所以,总之,
有没有办法允许某些Browserify导入具有全局作用域访问权限,或者使用window
对象作为其作用域运行?
我意识到这有安全隐患,但有select地使用,这将是非常有用的,同时需要像JavaScript库的东西,需要全局访问来正确设置自己。 任何帮助将不胜感激。
将小型库放入vendor.js中,使用<script>
将其包含到您的页面中,并使用browserify-shim
进行browserify,并在您的模块中使用require('libname')
。
可以从供应商的CDN中包含更大的库,也可以通过browserify-shim进行浏览。
的index.html
<html> <head> <script src="vendor.js"></script> <script src="bundle.js"></script> </head> <body> Open devtools and inspect the output </body> </html>
的package.json
{ "scripts": { "build": "cat vendor1.js vendor2.js > dist/vendor.js && cp index.html dist/index.html && browserify index.js -o dist/bundle.js" }, "browserify-shim" : { "vendor1" : "global:vendor1", "vendor2" : "global:vendor2" }, "browserify" : { "transform" : [ "browserify-shim" ] }, "devDependencies": { "browserify": "^14.1.0", "browserify-shim": "^3.8.14" }, "dependencies": { "moment": "^2.18.1", "moment-timezone": "^0.5.11" } }
关于上面的package.json
需要注意package.json
:
- 构build:它在dist文件夹中构build“应用程序”,创build以下结构:
- DIST
- 的index.html
- bundle.js
- vendor.js
- DIST
- “browserify”条目:它只是增加了browserify-shim
- “browserify-shim”条目:它告诉
vendor1
和vendor2
作为窗口(全局)对象上的属性可用。 Browserify不会试图捆绑它们,而require()
将只返回这些属性。 你需要确保它们实际上是可用的(所以上面的index.html
它们包含在<script src="vendor.js">
index.js
var momentfromnpm = require('moment-timezone'); var vendor1 = require('vendor1'); var vendor2 = require('vendor2'); console.log("Hello"); console.log("Using module from npm", momentfromnpm().tz("Europe/London").format()); console.log("using a function from vendor1.js (bundled into vendor.js)", vendor1()); console.log("using a 'module' from vendor2.js (bundled to vendor.js)", vendor2.doWork());
vendor1.js
window.vendor1 = function() { // could also be just `function vendor1()...` return "I'm a simple function, defined on a window"; };
vendor2.js
var vendor2 = { // could also be window.vendor2 doWork: function() { console.log("vendor2 doing work"); } };
按照网站上的指示安装moment-timezone
软件包。
npm install moment-timezone --save
在file1.js中 ,定义window.moment
为:
window.moment = require('moment-timezone/builds/moment-timezone-with-data-2010-2020');
这应该允许你在file2.js中使用moment().tz()