web-dev-qa-db-fra.com

"ReferenceError: WebSocket n'est pas défini" lors de l'utilisation de RxJs WebSocketSubject et Angular Universel

Je suis en train de mettre en place un projet angulaire 6.x univeral afin de tirer parti de ses fonctionnalités de rendu SSR (Server-Side Rendering). Dans mon application, j'utilise une communication websocket à l'aide de RxJs.

Plus précisément, j'utilise WebSocketSubject et webSocket dans mon projet angular universal 6.x, qui fonctionne bien sur la plate-forme de navigateur. Cependant, lors de l'exécution du serveur Web de noeud (qui contient la substance SSR (Rendu sur le serveur)), une erreur est générée:

ReferenceError: WebSocket n'est pas défini

Exemple de code:

// not actually code from the reproduction repo
import { WebSocketSubject, webSocket } from 'rxjs/webSocket';

const socket: WebSocketSubject<any> = webSocket('wss://echo.websocket.org');
socket.subscribe(msg => doSomething(msg));

Veuillez noter que l'erreur ne se produit pas sur la version du navigateur de l'application (c'est-à-dire que ng serve ne lève pas l'erreur), mais uniquement après avoir compilé les éléments SSR et exécuté le serveur Web express. Pour reproduire l'erreur, les builds doivent d'abord être exécutés:

# install dependencies
npm install

# build angular bundles for browser and server platforms
npm run build:client-and-server-bundles

# build the webserver
npm run webpack:server

# start the webserver
npm run serve:ssr

# the app is now being served at http://localhost:8081/
# open it in the browser and the error will occur: 'ReferenceError: WebSocket is not defined'

J'ai également mis en place un repo de reproduction .

Environnement que j'utilise:

  • Durée: Angular 6
  • Version RxJS: 6.2.0, 6.2.1, 6.2.2 (tous testés)

Modifier le 2018-08-02

J'ai pu aborder le problème avec plus de précision. Il semble que ce soit aussi un problème de Webpack. Angular Universal crée un bundle js pour l'exécution de l'application angular sur le serveur de nœud, mais il n'y a pas d'implémentation websocket en mode natif sur Node. Par conséquent, il doit être ajouté manuellement en tant que dépendance (package npm). J'ai essayé de l'ajouter au groupe de serveurs js (const WebSocket = require('ws'); manuellement, ce qui résout le problème} (c'est-à-dire que ReferenceError disparaît). ne fonctionnera pas.

Plus de détails

  • Le chargeur de packs Web ts-loader est utilisé pour compiler TypeScript => JavaScript
  • La dépendance websocket a été ajoutée à package.json: "ws": "^6.0.0"
  • Tenter de référencer la dépendance ws en ajoutant const WebSocket = require('ws'); au code TypeScript non compilé ne résoudra pas le problème. Il serait compilé dans var WebSocket = __webpack_require__(333); dans le fichier de sortie js, la dépendance ne pourra pas être résolue.
  • Manuellement changer var WebSocket = __webpack_require__(333); => const WebSocket = require('ws'); dans le fichier js compilé résoudrait le problème, mais bien sûr, c'est un hack.

Donc, les questions sont:

  • Puis-je "forcer" le pack Web à compiler la dépendance const WebSocket = require('ws'); => const WebSocket = require('ws'); (pas de modifications)?
  • Ou pourrait-il être une meilleure solution d'inscrire cette dépendance dans le package npm universal angular et de créer une demande d'extraction?
10
Ronin

Tout ce qu'il faut c'est ça:

// set WebSocket on global object
(global as any).WebSocket = require('ws');

Et bien sûr, nous avons également besoin de la dépendance ws dans le package.json:

npm i ws -s

2
Ronin