151 votes

Charger et exécuter un fichier js externe dans node.js avec accès aux variables locales ?

Est-il facile/possible de faire une simple include('./path/to/file') type de commande dans node.js ?

Tout ce que je veux faire, c'est accéder aux variables locales et exécuter un script. Comment les gens organisent-ils typiquement les projets node.js qui sont plus grands qu'un simple hello world ? (Un site web dynamique entièrement fonctionnel)

Par exemple, j'aimerais avoir des répertoires comme :

/models

/views

... etc

0 votes

Il est également possible d'inclure un script à partir d'une URL externe (au lieu d'un fichier local). Voir ici : pastebin.com/WkvHjGsG

0 votes

Le script ci-dessus ne fonctionne correctement que si vous créez un dossier appelé downloadedModules dans le même répertoire que le script.

149voto

Shripad K Points 6594

Il suffit de faire une require('./yourfile.js');

Déclarez toutes les variables auxquelles vous voulez accéder de l'extérieur comme des variables globales. Ainsi, au lieu de

var a = "hello" il le sera

GLOBAL.a="hello" ou simplement

a = "hello"

C'est évidemment une mauvaise chose. Vous ne voulez pas polluer le champ d'application global. Au lieu de cela, la méthode suggérée est de export vos fonctions/variables.

Si vous voulez le modèle MVC, jetez un coup d'œil à Geddy.

3 votes

En passant, j'adore Express. Vous devriez l'essayer aussi, même si vous n'êtes pas très porté sur le MVC.

48 votes

Lorsque vous dites "c'est manifestement mauvais", à quoi le terme "cela" fait-il référence ?

2 votes

@AndersonGreen - Il veut dire mettre les variables dans la portée globale.

100voto

Ivan Torres Points 514

Vous devez comprendre CommonJS, qui est un modèle de définition de modules. Vous ne devez pas abuser de la portée GLOBAL, c'est toujours une mauvaise chose à faire, à la place vous pouvez utiliser le jeton 'exports', comme ceci :

// circle.js

var PI = 3.14; // PI will not be accessible from outside this module

exports.area = function (r) {
  return PI * r * r;
};

exports.circumference = function (r) {
  return 2 * PI * r;
};

Et le code client qui utilisera notre module :

// client.js

var circle = require('./circle');
console.log( 'The area of a circle of radius 4 is '
           + circle.area(4));

Ce code a été extrait de la documentation API de node.js :

http://nodejs.org/docs/v0.3.2/api/modules.html

De plus, si vous voulez utiliser quelque chose comme Rails ou Sinatra, je vous recommande Express (je n'ai pas pu poster l'URL, honte à Stack Overflow !)

66voto

David Wolever Points 34304

Si vous écrivez du code pour Node, l'utilisation des modules Node tels que décrits par Ivan est sans aucun doute la meilleure solution.

Cependant, si vous avez besoin de charger du JavaScript qui a déjà été écrit et qui n'est pas conscient de l'existence d'un nœud, l'option vm est la meilleure solution (et certainement préférable au module eval ).

Par exemple, voici mon execfile qui évalue le script à path dans l'un ou l'autre context ou le contexte mondial :

var vm = require("vm");
var fs = require("fs");
module.exports = function(path, context) {
  var data = fs.readFileSync(path);
  vm.runInNewContext(data, context, path);
}

A noter également : les modules chargés avec require(…) n'ont pas accès au contexte global.

1 votes

Merci pour ce conseil. Le vrai cas d'utilisation est lorsque vous avez besoin de charger des modules adhoc. Par exemple, dans le cas d'un modèle d'enregistrement, vous avez 1000 modules qui s'enregistrent dans un service central. Il est beaucoup plus propre et mieux conçu de rechercher les modules et de les charger un par un plutôt que de faire 1000 instructions require dans votre service...

0 votes

Node supporte les requêtes dynamiques, il n'y a donc aucune raison d'utiliser ce modèle pour charger dynamiquement des modules compatibles avec Node. En fait, il est activement nuisible de l'utiliser, puisqu'il contourne la fonction require.cache Ainsi, un même fichier peut être chargé plusieurs fois.

0 votes

Ok, donc pour résoudre le cas que j'ai présenté où vous avez 1000 modules où chacun s'enregistre dans un service de registre, comment utiliser ce que vous avez proposé sans avoir 1000 instructions require dans le service de registre ?

12voto

Rox Points 11

Si vous prévoyez de charger les fonctions ou les objets d'un fichier javascript externe, chargez-les dans ce contexte en utilisant le code suivant - notez la méthode runInThisContext :

var vm = require("vm");
var fs = require("fs");

var data = fs.readFileSync('./externalfile.js');
const script = new vm.Script(data);
script.runInThisContext();

// here you can use externalfile's functions or objects as if they were instantiated here. They have been added to this context.

6voto

Jonathan Benn Points 176

Élargir le champ d'action @Shripad et @Ivan Je vous recommande d'utiliser la fonction standard de Node.js, à savoir la fonction module.export fonctionnalité.

Dans votre fichier pour les constantes ( par exemple constants.js ), vous écrirez des constantes comme ceci :

const CONST1 = 1;
module.exports.CONST1 = CONST1;

const CONST2 = 2;
module.exports.CONST2 = CONST2;

Ensuite, dans le fichier dans lequel vous voulez utiliser ces constantes, écrivez le code suivant :

const {CONST1 , CONST2} = require('./constants.js');

Si vous n'avez jamais vu le const { ... } syntaxe avant : c'est affectation de déstructuration .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X