Je veux ajouter ngx-socket-io à mon Angular application. J'utilise Bazel pour exécuter mon Angular dev-server. Malheureusement ngx-socket-io
ne semble pas fonctionner avec le ts_devserver
hors de la boîte. J'obtiens cette erreur dans la console du navigateur:
Uncaught TypeError: XMLHttpRequest is not a constructor
at ts_scripts.js?v=1587802098203:16776
at Object.23.../transport (ts_scripts.js?v=1587802098203:16780)
at o (ts_scripts.js?v=1587802098203:11783)
Cela semble être causé par xmlhttprequest-ssl qui est une dépendance de engine.io-client et il est nécessaire par ngx-socket-io
. Mais ce problème se produit uniquement avec ts_devserver . Exécuter l'application Angular app dans production fonctionne parfaitement.
Vous pouvez facilement l'essayer vous-même: https://github.com/flolu/bazel-socketio-issue
Exécutez simplement yarn install
puis yarn dev
(cela provoque l'erreur dans la console du navigateur @ http: // localhost: 42 ). Et notez que yarn prod
@ http: // localhost: 808 fonctionne très bien!
Actuellement, il semble y avoir un autre problème sous Windows. Vous ne pouvez donc essayer l'exemple de dépôt que si vous utilisez Mac ou Linux
Le problème vient de engine.io-client
, Qui est utilisé en interne par socket.io-client
:
Lorsque socket.io-client
Est construit en tant que module UMD déclenché par
"@npm//socket.io-client:socket.io-client__umd",
dans BUILD.bazel
, la touche browser
de engine.io-client/package.json
:
"browser": {
"ws": false,
"xmlhttprequest-ssl": "./lib/xmlhttprequest.js"
},
est apparemment ignoré.
Par conséquent, les instructions require('xmlhttprequest-ssl')
dans node_modules/engine.io-client/lib/transports/*.js
Restent dans la version UMD. Comme xmlhttprequest-ssl
Est destiné aux environnements sans tête Node et ne fonctionne pas dans les navigateurs, cela entraîne une erreur.
Je n'ai pas trouvé de raison/problème pour ce comportement, mais j'ai trouvé une solution (qui ne devrait pas être considérée comme une solution de contournement):
Réécrivez engine.io-client
Avec un script postinstall
:
shelljs
: yarn add -D shelljs
postinstall
dans package.json
à: "postinstall": "node --preserve-symlinks --preserve-symlinks-main ./postinstall-patches.js && ngcc"
postinstall-patches.js
à la racine du projet:try {
require.resolve('shelljs');
} catch (e) {
// We are in an bazel managed external node_modules repository
// and the resolve has failed because node did not preserve the symlink
// when loading the script.
// This can be fixed using the --preserve-symlinks-main flag which
// is introduced in node 10.2.0
console.warn(
`Running postinstall-patches.js script in an external repository requires --preserve-symlinks-main node flag introduced in node 10.2.0. ` +
`Current node version is ${process.version}. Node called with '${process.argv.join(' ')}'.`);
process.exit(0);
}
const {set, cd, sed, ls} = require('shelljs');
const path = require('path');
const log = console.info;
log('===== about to run the postinstall-patches.js script =====');
// fail on first error
set('-e');
// print commands as being executed
set('-v');
cd(__dirname);
log('\n# patch engine.io-client: rewriting \'xmlhttprequest-ssl\' to browser shim');
ls('node_modules/engine.io-client/lib/transports/*.js').forEach(function (file) {
sed('-i', '\'xmlhttprequest-ssl\'', '\'../xmlhttprequest\'', file);
});
log('===== finished running the postinstall-patches.js script =====');
(Inspiration: https://bazelbuild.github.io/rules_nodejs/#patching-the-npm-packages , qui renvoie à l'exemple https://github.com/angular/ angular/blob/master/tools/postinstall-patches.js )
yarn install
yarn dev
Je soumettrai une demande d'extraction à votre repro GitHub dans quelques minutes.
Alternatives possibles , impossible de les faire fonctionner:
socket.io-client/dist/socket.io.js
mais avec un "shim UMD" supplémentaire car il semble être un module "UMD anonyme", OUnpm_umd_bundle
Voir le problème Chaque nouveau dépôt npm nécessite une approche unique pour l'ajouter à ts_devserver # 1055 in bazelbuild/rules_nodejs
pour plus d'informations sur les deux méthodes.