我正在尝试将浏览器端库的运行时环境扩展到 node.js。我实现了通用模块定义(UMD)模式来做到这一点。它适用于 AMD 实现,<script>
但不适用于 node.js,因为没有window
.
有问题的依赖项是WebSocket
, EventSource
, XMLHttpRequest
, document
. 此处描述了详细信息:https ://github.com/flowersinthesand/portal/issues/115那么解决 node.js 中的窗口依赖关系的最佳方法是什么?我有以下方法可以做到这一点。由于我是 node.js 的新手,这些有点陌生,我不知道哪种方式是自然的。虽然我正在尝试支持 node.js,但我不想改变太多东西。
以下代码片段来自https://github.com/flowersinthesand/portal/blob/master/portal.js
使用 jsdom
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(function() {
// Passes the window
return factory(root);
});
} else if (typeof exports === 'object') {
// Node
module.exports = factory(require('jsdom').something);
} else {
// Browser globals, Window
root.portal = factory(root);
}
}(this, function(window) {
如果 jsdom 很好地支持上述依赖项,这看起来最好。但是,如果它有效,我想知道为什么 sockjs、socket.io 和 engine.io 的客户端不使用 jsdom。也许,它们是针对节点而不是浏览器的?表现?
使窗口成为一个普通的依赖对象
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(function() {
// Passes the window
return factory(root);
});
} else if (typeof exports === 'object') {
// Node
module.exports = factory({
WebSocket: require('package name for WebSocket').something,
EventSource: require('package name for EventSource').something,
document: require('jsdom').hmm,
// ...
});
} else {
// Browser globals, Window
root.portal = factory(root);
}
}(this, function(window) {
做一组依赖,window,看起来很挑剔,有点不舒服,但是,如果可能的话,我想保留当前的代码。此外,当 XMLHttpRequest 由于跨域或卸载事件而无法工作并且这种情况包括 IE 6 时,可能还需要 jsdom 来通过脚本标记解析用于执行 HTTP 请求的文档,这种情况包括 IE 6。可以使用文档来分离逻辑以使用某些东西浏览器中的节点和脚本标签支持检查当前运行时是什么,但这对我来说是一个很大的变化。