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:
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
ts-loader
est utilisé pour compiler TypeScript => JavaScript"ws": "^6.0.0"
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.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:
const WebSocket = require('ws');
=> const WebSocket = require('ws');
(pas de modifications)?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