【问题标题】:How to load signalr.js in webpack inside Angular 2如何在 Angular 2 中的 webpack 中加载 signalr.js
【发布时间】:2017-02-23 02:36:58
【问题描述】:

我总是收到一条消息说:

$.hubConnection 不是函数

错误:没有找到 jQuery。请确保之前引用了 jQuery SignalR 客户端 JavaScript 文件。安慰“$”和“jquery”是 未定义。

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

【问题讨论】:

    标签: angular webpack signalr


    【解决方案1】:

    干净的解决方案:使用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 中

    【讨论】:

    • 这可以加载 jQuery 和 signalR,但我仍然无法调用 $.connection.myHub,因为未加载集线器代理。如何使用 webpack 实现这一点?
    • 使用动态生成的信号器/集线器脚本是可选的。目前我不使用它,在我的 webpack 环境中。
    • 使用动态生成的信号器/集线器脚本是可选的。我使用 $.hubConnection(this.url) & connection.createHubProxy(this.hubName) 并且它有效。
    • 谢谢,确实 import import 'expose-loader?jQuery!jquery' 是在 Webpack 中使用 signalR 的解决方案。我调用服务器方法 $.connection['myHub'].server.chat( message ) 或客户端方法 $.connection['myHub'].client.chat = ( message : string ) => { ... }.
    【解决方案2】:

    感谢 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"
    }
    

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

    【讨论】:

      【解决方案3】:

      扩展 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';
      

      【讨论】:

        猜你喜欢
        • 2017-12-27
        • 2017-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多