Il existe des bibliothèques Javascript tierces qui ont des fonctionnalités que je voudrais utiliser dans un serveur Node.js. (Plus précisément, je veux utiliser une bibliothèque javascript QuadTree que j'ai trouvée.) Mais ces bibliothèques ne sont que des .js
fichiers simples et non des "bibliothèques Node.js".
En tant que telles, ces bibliothèques ne suivent pas la exports.var_name
syntaxe attendue par Node.js pour ses modules. Pour autant que je sache, cela signifie quand vous faites module = require('module_name');
ou module = require('./path/to/file.js');
vous vous retrouverez avec un module sans fonctions accessibles au public, etc.
Ma question est alors "Comment charger un fichier javascript arbitraire dans Node.js de manière à pouvoir utiliser ses fonctionnalités sans avoir à le réécrire pour qu'il le fasse exports
?"
Je suis très nouveau sur Node.js, alors faites-moi savoir s'il y a un trou flagrant dans ma compréhension de son fonctionnement.
EDIT : En recherchant davantage et je vois maintenant que le modèle de chargement de module utilisé par Node.js fait en fait partie d'un standard récemment développé pour le chargement de bibliothèques Javascript appelé CommonJS . Il dit cela directement sur la page de documentation du module pour Node.js , mais je l'ai manqué jusqu'à présent.
Il se peut que la réponse à ma question soit "attendez que les auteurs de votre bibliothèque se mettent à écrire une interface CommonJS ou faites-le vous-même".
la source
Réponses:
Il existe une bien meilleure méthode que d'utiliser
eval
: levm
module.Par exemple, voici mon
execfile
module, qui évalue le scriptpath
dans l'uncontext
ou l'autre contexte global:Et il peut être utilisé comme ceci:
Où
example.js
contient:Le gros avantage de cette méthode est que vous avez un contrôle complet sur les variables globales dans le script exécuté: vous pouvez passer des globaux personnalisés (via
context
), et tous les globaux créés par le script seront ajoutéscontext
. Le débogage est également plus facile car les erreurs de syntaxe et autres seront signalées avec le nom de fichier correct.la source
runInNewContext
le contexte global sicontext
(autrement appelésandbox
, dans la documentation) n'est pas défini? (ce point n'a été clarifié par aucun document que j'ai trouvé)vm
module peut-il offrir dans ce cas?Voici ce que je pense être la réponse «la plus juste» à cette situation.
Supposons que vous ayez un fichier de script appelé
quadtree.js
.Vous devez créer une personnalisation
node_module
qui a ce type de structure de répertoires ...Tout ce qui se trouve dans votre
./node_modules/quadtree/quadtree-lib/
répertoire est constitué de fichiers de votre bibliothèque tierce.Ensuite, votre
./node_modules/quadtree/index.js
fichier chargera simplement cette bibliothèque à partir du système de fichiers et effectuera le travail d'exportation des choses correctement.Vous pouvez maintenant utiliser votre
quadtree
module comme n'importe quel autre module de nœud ...J'aime cette méthode car il n'est pas nécessaire de changer le code source de votre bibliothèque tierce - c'est donc plus facile à maintenir. Tout ce que vous avez à faire lors de la mise à niveau est de consulter leur code source et de vous assurer que vous exportez toujours les objets appropriés.
la source
npm link
dans votre application. Ensuite, il est traité comme s'il s'agissait d'un package Node.js natif.Le moyen le plus simple est:
eval(require('fs').readFileSync('./path/to/file.js', 'utf8'));
Cela fonctionne très bien pour les tests dans le shell interactif.la source
AFAIK, c'est bien ainsi que les modules doivent être chargés. Cependant, au lieu de coller toutes les fonctions exportées sur l'
exports
objet, vous pouvez également les coller surthis
(ce qui serait autrement l'objet global).Donc, si vous souhaitez garder les autres bibliothèques compatibles, vous pouvez le faire:
ou, lorsque la bibliothèque externe a déjà son propre espace de noms, par exemple
jQuery
(pas que vous pouvez utiliser que dans un environnement côté serveur):Dans un environnement non-Node,
this
se résoudrait à l'objet global, en faisant ainsi une variable globale ... ce qu'il était déjà. Donc ça ne devrait rien casser.Edit : James Herdman a un bel article sur node.js pour les débutants, qui le mentionne également.
la source
Je ne sais pas si je finirai par l'utiliser car c'est une solution plutôt pirate, mais une solution consiste à créer un petit importateur de mini-modules comme celui-ci ...
Dans le fichier
./node_modules/vanilla.js
:Ensuite, lorsque vous souhaitez utiliser les fonctionnalités de votre bibliothèque, vous devez choisir manuellement les noms à exporter.
Donc pour une bibliothèque comme le fichier
./lib/mylibrary.js
...Lorsque vous souhaitez utiliser ses fonctionnalités dans votre code Node.js ...
Je ne sais pas si tout cela fonctionnerait dans la pratique.
la source
J'ai pu le faire fonctionner en mettant à jour leur script, très facilement, en ajoutant simplement le
module.exports =
cas échéant ...Par exemple, j'ai pris leur fichier et j'ai copié dans './libs/apprise.js'. Alors où ça commence par
J'ai assigné la fonction à
module.exports =
ainsi:Ainsi, je suis capable d'importer la bibliothèque dans mon code comme ceci:
Et j'étais prêt à partir. YMMV, c'était avec webpack .
la source
Une
include(filename)
fonction simple avec une meilleure messagerie d'erreur (pile, nom de fichier etc.) poureval
, en cas d'erreurs:Mais cela devient encore plus sale avec nodejs: vous devez spécifier ceci:
Sinon, vous ne pouvez pas utiliser de variables globales dans les fichiers inclus avec
include(...)
.la source