Javascript 扩展浏览器本机类时使用Webpack

Javascript 扩展浏览器本机类时使用Webpack,javascript,reactjs,typescript,webpack,Javascript,Reactjs,Typescript,Webpack,我正在使用带有React和Typescript的Webpack,并尝试为WebSocket创建一个包装器类,一个浏览器本机类 该类位于文件webSocketConnection.ts中,看起来如下所示: export default class WebSocketConnection extends WebSocket { constructor(url: string, protocols?: string | string[]) { super(url, protoc

我正在使用带有React和Typescript的Webpack,并尝试为WebSocket创建一个包装器类,一个浏览器本机类

该类位于文件
webSocketConnection.ts
中,看起来如下所示:

export default class WebSocketConnection extends WebSocket {
    constructor(url: string, protocols?: string | string[]) {
        super(url, protocols);
    }
}
///Inside of file webSocketConnection.js
let classVar;

if (typeof(WebSocket) !== 'undefined') {
    classVar = class WebSocketConnection extends WebSocket {
        constructor(url, protocols) {
            super(url, protocols);
        }
    }
}

export default function(url, protocols) {
    return new classVar(url, protocols);
}
一个单独的文件导入并使用它

import WebSocketConnection from './webSocketConnection';

export function Connect() {
    return new WebSocketConnection("<<someUrl>>");
}
下午2点36分更新 传输后的结果如下所示:

var WebSocketConnection = (function (_super) {
    __extends(WebSocketConnection, _super);
    function WebSocketConnection(url, protocols) {
        return _super.call(this, url, protocols) || this;
    }
    return WebSocketConnection;
}(WebSocket));

下午6:42更新:进一步测试后,原始答案确实正确生成,但运行不正确。尽管将原型显式设置为WebSocket,但它仍然在
super()
期间调用WebSocketMock

第二种方法确实有效,但却发现在Chrome中根本无法扩展WebSocket,因为在构造“WebSocket”时总是会出现错误
:请使用“new”运算符,此DOM对象构造函数不能作为函数调用。

如果其他人需要扩展可以扩展的浏览器本机类,那么这就是成功实现的方式:

///Inside of file webSocketConnection.ts
export interface WebSocketConnection extends WebSocket {
    //Custom properties here
}

let classVar: any;

if (typeof(WebSocket) !== 'undefined') {
    classVar= class WebSocketConnection extends WebSocket {
        constructor(url: string, protocols?: string | string[]) {
            super(url, protocols);
        }
    }
}

export default function(url: string, protocols?: string | string[]): WebSocketConnection {
    return new classVar(url, protocols) as WebSocketConnection;
}
--

--

如果没有typescript,它可能看起来像这样(我没有一个没有typescript的环境,可以使用Webpack进行测试)


我会先检查传输的结果我已经添加了结果。可以看出为什么WebSocket会在节点中爆炸。不确定如何更改原始代码以输出不会爆炸的内容。是否将其称为
窗口。WebSocket
帮助?由于typescript,窗口无法工作,因为它不包含WebSocket,但它让我想到尝试一些选项。谢谢如果您在node中运行这段代码,那么就我所知,node当然既没有窗口也没有websocket
///Inside of a second file
import createWebSocket, { WebSocketConnection } from './webSocketConnection';

function DoSomething() {
    //Note no "new" keyword used, because this function isn't actually a constructor
    let socket: WebSocketConnection = createWebSocket("<<someUrl>>");
}
///Inside of file webSocketConnection.js
let classVar;

if (typeof(WebSocket) !== 'undefined') {
    classVar = class WebSocketConnection extends WebSocket {
        constructor(url, protocols) {
            super(url, protocols);
        }
    }
}

export default function(url, protocols) {
    return new classVar(url, protocols);
}
///Inside of a second file
import createWebSocket from './webSocketConnection';

function DoSomething() {
    //Note no "new" keyword used, because this function isn't actually a constructor
    let socket = createWebSocket("<<someUrl>>");
}
/* Mock class = WebSocketMock; new empty class that looks similar to original class
 * Original class = WebSocket; browser-only class we want to extend
 * New class = WebSocketConnection; class that extends original class
 */

/* Creating a blank interface, with the same name as the mock class,
 * that extends the original interface we're trying to mock
 * allows the mock class to have all the properties of the original class
 * without having to actually implement blank versions of them
 */
interface WebSocketMock extends WebSocket {
}

/* The mock class must have the same constructor as the original class
 * so that the new class can use super() with the right signature
 */
class WebSocketMock {
    constructor(url: string, protocols?: string | string[]) {
    }
}

// New class extends the mock class
export default class WebSocketConnection extends WebSocketMock {
    constructor(url: string, protocols?: string | string[]) {
        super(url, protocols);
    }

    //Other properties and code will be added here
}

/* Updates the prototype of the new class to use the original class
 * when the original class exists. Of course, if you try to use the new
 * class in an environment (read: browser) that doesn't have the original
 * class, everything would break, as it's just an empty "shim"
 */
if (typeof (WebSocket) !== 'undefined')
    Object.setPrototypeOf(WebSocketConnection, WebSocket);
class WebSocketMock {
    constructor(url, protocols) {
    }
}

export default class WebSocketConnection extends WebSocketMock {
    constructor(url, protocols) {
        super(url, protocols);
    }

    //Other properties and code will be added here
}

if (typeof (WebSocket) !== 'undefined')
    Object.setPrototypeOf(Object.getPrototypeOf(WebSocketConnection), WebSocket);