如何在webpack里面加载signalr.js Angular 2

How to load signalr.js in webpack inside Angular 2

我总是收到一条消息说:

$.hubConnection 不是函数

Error: jQuery was not found. Please ensure jQuery is referenced before the SignalR client JavaScript file. consoling out "$" and "jquery" is undefined.

我需要做什么才能让 signalr 使用 webpack 工作?

清理解决方案:使用 expose-loader !!

npm install expose-loader --save-dev

在你的vendor.ts

里面
import 'expose-loader?jQuery!jquery';
import '../node_modules/signalr/jquery.signalR.js';

在你的webpack.config.ts

里面
new ProvidePlugin({ jQuery: 'jquery', $: 'jquery', jquery: 'jquery' })

说明: jquery.signalR.js脚本确实没有写成umd模块。这使得它在默认情况下不能被 webpack 加载。它不需要 jquery,但假设 Jquery 存在于全局变量 window.jQuery 上。我们可以通过使用 expose-loader 导入 jquery 模块来在 webpack 中完成这项工作。此加载程序将确保 jquery 的导出值暴露给 jQuery 全局变量。因此允许加载 signalr.js 脚本作为下一个模块。

此外,如果您以后想通过 $ 使用 signalr,您还必须使用 jquery 模块的 provideplugin。里面 webpack.config.js

感谢 hannes 和 this guide from Microsoft 我设法让 SignalR 使用 ES6 语法与 Webpack 和 TypeScript 一起工作。

之前:

///<reference path="./vendor/typings/signalr/signalr.d.ts"/>

interface SignalR {
    myHub: Some.Stuff.IMyHubProxy;
}

namespace MyWebsite.Stuff {
    export class SignalRConnectionService {
        ...
        public start() {
            var myHubProxy = $.connection.myHub;

            myHubProxy.client.onSomethingChanged = (eventArgs) => {
                // do stuff
            };

            $.connection.hub.start();
        }
    }
}

之后:

import "signalR";

export class SignalRConnectionService {
    public start() {
        ...
        const hubConnection = $.hubConnection();
        const myHubProxy = hubConnection.createHubProxy('myHub');

        myHubProxy.on('onSomethingChanged', (summary) => {
            // do stuff
        });

        hubConnection.start();
    }
}

webpack.config.js:

plugins: [
    new webpack.ProvidePlugin({
        $: "jquery",
        'window.jQuery': 'jquery',
        jQuery: "jquery"
    })
]

packages.json:

"dependencies": {
  "jquery": "~2.1.4",
  "signalr": "~2.2.3"
}

注意:您还需要删除 <script src="/signalR/hubs"/> 的加载,因为它不再需要。

扩展 Hannes Neukermans 的回答:

使用 webpack.ProvidePlugin 使 jQuery 全局可用,但它也让 jQuery 进入了它不应该进入的中间位置。例如,它用 jQuery-specific 对象包装一些事件 (KeyboardEvent => jQuery.Event).

最好不要使用 webpack.ProvidePlugin,而只使用 expose-loader

在你的webpack.config.js中:

module: {
    rules: [
        {
            test: require.resolve('jquery'),
            use: [
                {
                    loader: 'expose-loader',
                    options: 'jQuery'
                },
                {
                    loader: 'expose-loader',
                    options: '$'
                }
            ]
        }
    ]
}

您仍然需要在 vendor.ts 中导入 signalR 和 jQuery:

import 'jquery';
import 'signalR';