有没有办法允许 browserify 模块访问全局范围(window 对象)?
Is there a way to allow browserify modules access to the global scope (window object)?
场景
我正在使用 Browserify(或 NodeJS/CommonJS 类似导入)来获取一些 JavaScript 库。但是,我很难让它们发挥出色,因为显然 Browserify 默认情况下拒绝对所有模块进行全局范围访问。例如,这样做是行不通的;
file1.js
require('moment');
file2.js
moment(new Date()); // throws moment is undefined
但这可以通过将 file1.js 的内容更改为以下内容来实现;
window.moment = require('moment');
问题
到目前为止,这已经足够好了,但是现在我在加载 moment 时区库(MomentJS 的扩展)时遇到了问题。 Moment Timezone 的文档暗示这两个脚本应该 运行 在 window 全局范围内,方法是将它们添加为脚本标签,如下所示;
<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
对象作为其范围?
我知道这有安全隐患,但有选择地使用,这将非常有用,同时需要像 JavaScript 需要全局访问权限的库才能正确设置自己。任何帮助将不胜感激。
将小型库放入 vendor.js,使用 <script>
将其包含在您的页面上,使用 browserify-shim
让 browserify
知道它们并使用它们 require('libname')
在你的模块中。
更大的库可能包含在供应商 CDN 中,并且也可以使用 browserify-shim 使 browserify 知道。
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
:
- build:它在 dist 文件夹中构建 'application',创建以下结构:
- 距离
- index.html
- bundle.js
- vendor.js
- "browserify"条目:它只是添加了browserify-shim
- "browserify-shim" 条目:它告诉 browserify
vendor1
和 vendor2
可用作 window(全局)对象的属性。 Browserify 不会尝试捆绑它们,require()
只会 return 这些属性。您需要确保它们确实可用(因此上面的 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");
}
};
按照 website 上的说明安装 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()
场景
我正在使用 Browserify(或 NodeJS/CommonJS 类似导入)来获取一些 JavaScript 库。但是,我很难让它们发挥出色,因为显然 Browserify 默认情况下拒绝对所有模块进行全局范围访问。例如,这样做是行不通的;
file1.js
require('moment');
file2.js
moment(new Date()); // throws moment is undefined
但这可以通过将 file1.js 的内容更改为以下内容来实现;
window.moment = require('moment');
问题
到目前为止,这已经足够好了,但是现在我在加载 moment 时区库(MomentJS 的扩展)时遇到了问题。 Moment Timezone 的文档暗示这两个脚本应该 运行 在 window 全局范围内,方法是将它们添加为脚本标签,如下所示;
<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
对象作为其范围?
我知道这有安全隐患,但有选择地使用,这将非常有用,同时需要像 JavaScript 需要全局访问权限的库才能正确设置自己。任何帮助将不胜感激。
将小型库放入 vendor.js,使用 <script>
将其包含在您的页面上,使用 browserify-shim
让 browserify
知道它们并使用它们 require('libname')
在你的模块中。
更大的库可能包含在供应商 CDN 中,并且也可以使用 browserify-shim 使 browserify 知道。
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
:
- build:它在 dist 文件夹中构建 'application',创建以下结构:
- 距离
- index.html
- bundle.js
- vendor.js
- 距离
- "browserify"条目:它只是添加了browserify-shim
- "browserify-shim" 条目:它告诉 browserify
vendor1
和vendor2
可用作 window(全局)对象的属性。 Browserify 不会尝试捆绑它们,require()
只会 return 这些属性。您需要确保它们确实可用(因此上面的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");
}
};
按照 website 上的说明安装 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()