【发布时间】:2017-02-23 02:36:58
【问题描述】:
我总是收到一条消息说:
$.hubConnection 不是函数
错误:没有找到 jQuery。请确保之前引用了 jQuery SignalR 客户端 JavaScript 文件。安慰“$”和“jquery”是 未定义。
我需要做什么才能让 Signalr 使用 webpack 工作?
【问题讨论】:
我总是收到一条消息说:
$.hubConnection 不是函数
错误:没有找到 jQuery。请确保之前引用了 jQuery SignalR 客户端 JavaScript 文件。安慰“$”和“jquery”是 未定义。
我需要做什么才能让 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 中
【讨论】:
$.connection.myHub,因为未加载集线器代理。如何使用 webpack 实现这一点?
感谢 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 的对象 (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';
【讨论】: