Le problème lorsqu'on essaie de déterminer dans quel environnement le code s'exécute, c'est que n'importe quel objet peut être modifié et déclaré, ce qui rend presque impossible de déterminer quels objets sont natifs de l'environnement et lesquels ont été modifiés par le programme.
Cependant, il existe quelques astuces permettant de déterminer avec certitude l'environnement dans lequel vous vous trouvez.
Commençons par la solution généralement acceptée qui est utilisée dans la bibliothèque underscore :
typeof module !== 'undefined' && module.exports
Cette technique est en fait parfaitement adaptée au côté serveur, car lorsque la fonction require
est appelée, elle réinitialise le this
en un objet vide, et redéfinit l'objet module
pour vous, ce qui signifie que vous n'avez pas à vous soucier d'une quelconque altération extérieure. Tant que votre code est chargé avec require
vous êtes en sécurité.
Cependant, cela s'écroule sur le navigateur, car n'importe qui peut facilement définir module
pour faire croire que c'est l'objet que vous recherchez. D'un côté, c'est peut-être le comportement que vous souhaitez, mais il dicte également quelles variables l'utilisateur de la bibliothèque peut utiliser dans la portée globale. Peut-être que quelqu'un veut utiliser une variable portant le nom de module
qui a exports
à l'intérieur de celui-ci pour une autre utilisation. C'est peu probable, mais qui sommes-nous pour juger des variables que quelqu'un d'autre peut utiliser, juste parce qu'un autre environnement utilise ce nom de variable ?
L'astuce cependant, est que si nous supposons que votre script est chargé dans la portée globale (ce qui sera le cas s'il est chargé via une balise script), une variable ne peut pas être réservée dans une fermeture externe, car le navigateur ne le permet pas. Maintenant, rappelez-vous que dans node, la balise this
est un objet vide, pourtant, l'objet module
est toujours disponible. C'est parce qu'elle est déclarée dans une fermeture externe. Nous pouvons donc corriger la vérification d'underscore en ajoutant une vérification supplémentaire :
this.module !== module
Avec cela, si quelqu'un déclare module
dans l'étendue globale du navigateur, il sera placé dans l'étendue globale de l'application. this
ce qui entraînera l'échec du test car this.module
sera le même objet que le module. Sur le nœud, this.module
n'existe pas, et module
existe à l'intérieur d'une fermeture externe, donc le test réussira, car ils ne sont pas équivalents.
Ainsi, le test final est :
typeof module !== 'undefined' && this.module !== module
Remarque : Bien que cela permette maintenant à l module
pour être utilisée librement dans la portée globale, il est toujours possible de contourner cela dans le navigateur en créant une nouvelle fermeture et en déclarant module
à l'intérieur de celle-ci, puis en chargeant le script à l'intérieur de cette fermeture. À ce stade, l'utilisateur reproduit entièrement l'environnement du nœud et, avec un peu de chance, sait ce qu'il fait et essaie de faire un require de style nœud. Si le code est appelé dans une balise script, il sera toujours à l'abri de toute nouvelle fermeture externe.
3 votes
Je n'en ai aucune idée. por qué vous essayez de le faire, mais en règle générale, vous devriez utiliser la détection des caractéristiques plutôt que celle des moteurs. quirksmode.org/js/support.html
4 votes
Il s'agit en fait d'une demande sur la manière d'implémenter la détection des caractéristiques, mais la question se décrit mal.
0 votes
J'ai publié une bibliothèque pour mon propre usage, cela m'aidera. npmjs.com/package/detect-is-node
0 votes
Voir stackoverflow.com/questions/17575790/
0 votes
L'un des problèmes de la question, et de la plupart des réponses, est l'hypothèse selon laquelle il n'y a que deux possibilités : Navigateur ou Node.js. Il est possible qu'il ne s'agisse ni d'un navigateur ni de Node.js, comme c'est le cas avec Oracle Java Nashorn. Si le JDK est installé, la commande jjs vous permet d'exécuter des scripts. Mais il existe de nombreuses différences entre Nashorn et Node.js, vous ne pouvez donc pas faire de supposition. Et qui sait quelles options l'avenir peut apporter ? La détection des fonctionnalités est nécessaire.
0 votes
@user314159 Vous avez raison. Beaucoup de choses ont changé en 9 ans, la question avait du sens à l'époque où elle a été postée.
0 votes
La question n'avait pas nécessairement de sens, même à cette époque, il y a 9 ans. C'est ce que je veux dire. Même il y a 20 ans, il y avait de multiples moteurs javascript et environnements d'hébergement. Le fait est que nous ne pouvons pas faire d'hypothèses, ni dans les questions ni dans les réponses. Si nous avons des contraintes ou des critères explicitement énoncés et que nous souhaitons limiter le domaine de considération par souci de concision, c'est une chose. Cela peut être valable dans certaines circonstances. Mais il faut reconnaître qu'une telle question n'est pas complète. Sinon, nous faisons des discussions et des communautés basées sur des préjugés.
0 votes
Cela répond-il à votre question ? Comment détecter si script s'exécute dans le navigateur ou dans Node.js ?