Disons que j'ai un fichier appelé app.js. Assez simple:
var express = require('express');
var app = express.createServer();
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.get('/', function(req, res){
res.render('index', {locals: {
title: 'NowJS + Express Example'
}});
});
app.listen(8080);
Et si j'ai des fonctions dans "tools.js". Comment pourrais-je les importer pour les utiliser dans apps.js?
Ou ... suis-je censé transformer des "outils" en un module, puis en avoir besoin? << semble difficile, je préfère faire l'importation de base du fichier tools.js.
Vous pouvez exiger n'importe quel fichier js, il vous suffit de déclarer ce que vous voulez exposer.
// tools.js
// ========
module.exports = {
foo: function () {
// whatever
},
bar: function () {
// whatever
}
};
var zemba = function () {
}
Et dans votre fichier d'application:
// app.js
// ======
var tools = require('./tools');
console.log(typeof tools.foo); // => 'function'
console.log(typeof tools.bar); // => 'function'
console.log(typeof tools.zemba); // => undefined
Si, malgré toutes les autres réponses, vous souhaitez toujours traditionnellement inclure un fichier dans un fichier source node.js, vous pouvez utiliser ceci:
var fs = require('fs');
// file is included here:
eval(fs.readFileSync('tools.js')+'');
+''
est nécessaire pour obtenir le contenu du fichier sous forme de chaîne et non d'objet (vous pouvez également utiliser .toString()
si vous préférez).include()
ou quelque chose du genre).Veuillez noter que dans la plupart des cas, il s'agit de mauvaise pratique et que vous devriez plutôt écrire un module . Cependant, il existe des situations rares où la pollution de votre contexte local/espace de noms est ce que vous voulez vraiment.
Notez également que cela ne fonctionnera pas avec "use strict";
(lorsque vous êtes en "mode strict" ) car les fonctions et les variables définies dans le fichier "importé" ne sont pas accessibles par le code qui fait l'importation. Le mode strict applique certaines règles définies par les versions les plus récentes du standard de langage. Ceci peut être une autre raison pour éviter la solution décrite ici.
Vous n'avez besoin ni de nouvelles fonctions ni de nouveaux modules . Vous devez simplement exécuter le module que vous appelez si vous ne voulez pas utiliser d'espace de nom.
module.exports = function() {
this.sum = function(a,b) { return a+b };
this.multiply = function(a,b) { return a*b };
//etc
}
ou dans tout autre fichier .js comme myController.js:
au lieu de
var tools = require('tools.js')
qui nous oblige à utiliser un espace de noms et à appeler des outils comme tools.sum(1,2);
nous pouvons simplement appeler
require('tools.js')();
et alors
sum(1,2);
dans mon cas, j'ai un fichier avec les contrôleurs ctrls.js
module.exports = function() {
this.Categories = require('categories.js');
}
et je peux utiliser Categories
dans chaque contexte en tant que classe publique après require('ctrls.js')()
Créer deux fichiers js
// File cal.js
module.exports = {
sum: function(a,b) {
return a+b
},
multiply: function(a,b) {
return a*b
}
};
Fichier js principal
// File app.js
var tools = require("./cal.js");
var value = tools.sum(10,20);
console.log("Value: "+value);
Sortie
value: 30
Voici une explication simple et claire:
// Include the public functions from 'helpers.js'
var helpers = require('./helpers');
// Let's assume this is the data which comes from the database or somewhere else
var databaseName = 'Walter';
var databaseSurname = 'Heisenberg';
// Use the function from 'helpers.js' in the main file, which is server.js
var fullname = helpers.concatenateNames(databaseName, databaseSurname);
// 'module.exports' is a node.JS specific feature, it does not work with regular JavaScript
module.exports =
{
// This is the function which will be called in the main file, which is server.js
// The parameters 'name' and 'surname' will be provided inside the function
// when the function is called in the main file.
// Example: concatenameNames('John,'Doe');
concatenateNames: function (name, surname)
{
var wholeName = name + " " + surname;
return wholeName;
},
sampleFunctionTwo: function ()
{
}
};
// Private variables and functions which will not be accessible outside this file
var privateFunction = function ()
{
};
Je recherchais également une fonction 'include' de NodeJS et j'ai vérifié la solution proposée par Udo G - voir le message https://stackoverflow.com/a/8744519/2979590 . Son code ne fonctionne pas avec mes fichiers JS inclus ..__ Enfin, j'ai résolu le problème de la manière suivante:
var fs = require("fs");
function read(f) {
return fs.readFileSync(f).toString();
}
function include(f) {
eval.apply(global, [read(f)]);
}
include('somefile_with_some_declarations.js');
Bien sûr, ça aide.
Le module vm de Node.js permet d'exécuter du code JavaScript dans le contexte actuel (y compris l'objet global). Voir http://nodejs.org/docs/latest/api/vm.html#vm_vm_runinthiscontext_code_filename
Notez que, à ce jour, il existe un bogue dans le module vm qui empêche runInThisContext de faire le bon droit lorsqu'il est appelé depuis un nouveau contexte. Cela n'a d'importance que si votre programme principal exécute le code dans un nouveau contexte et que ce code appelle runInThisContext. Voir https://github.com/joyent/node/issues/898
Malheureusement, l'approche avec (globale) suggérée par Fernando ne fonctionne pas pour les fonctions nommées telles que "function foo () {}"
En bref, voici une fonction include () qui fonctionne pour moi:
function include(path) {
var code = fs.readFileSync(path, 'utf-8');
vm.runInThisContext(code, path);
}
disons que nous voulons appeler la fonction ping () et add (30,20) qui se trouve dans lib.js fichier depuis main.js
main.js
lib = require("./lib.js")
output = lib.ping();
console.log(output);
//Passing Parameters
console.log("Sum of A and B = " + lib.add(20,30))
lib.js
this.ping=function ()
{
return "Ping Success"
}
//Functions with parameters
this.add=function(a,b)
{
return a+b
}
Udo G. a déclaré:
- Eval () ne peut pas être utilisé dans une fonction et doit être appelé à l'intérieur la portée globale sinon aucune fonction ou variable ne sera accessible (c’est-à-dire que vous ne pouvez pas créer une fonction utilitaire include () ou quelque chose comme ça).
Il a raison, mais il y a un moyen d'affecter la portée globale d'une fonction. Améliorer son exemple:
function include(file_) {
with (global) {
eval(fs.readFileSync(file_) + '');
};
};
include('somefile_with_some_declarations.js');
// the declarations are now accessible here.
J'espère que cela pourra aider.
Une autre façon de faire cela, à mon avis, est d'exécuter tout dans le fichier lib quand vous appelez la fonction require () en utilisant (fonction (/ * choses ici * /) {}) (); faire cela rendra toutes ces fonctions globales, exactement comme la solution eval ()
src/lib.js
(function () {
funcOne = function() {
console.log('mlt funcOne here');
}
funcThree = function(firstName) {
console.log(firstName, 'calls funcThree here');
}
name = "Mulatinho";
myobject = {
title: 'Node.JS is cool',
funcFour: function() {
return console.log('internal funcFour() called here');
}
}
})();
Et ensuite, dans votre code principal, vous pouvez appeler vos fonctions par leur nom, par exemple:
main.js
require('./src/lib')
funcOne();
funcThree('Alex');
console.log(name);
console.log(myobject);
console.log(myobject.funcFour());
Fera cette sortie
bash-3.2$ node -v
v7.2.1
bash-3.2$ node main.js
mlt funcOne here
Alex calls funcThree here
Mulatinho
{ title: 'Node.JS is cool', funcFour: [Function: funcFour] }
internal funcFour() called here
undefined
Faites attention au undefined lorsque vous appelez mon object.funcFour (), ce sera la même chose si vous chargez avec eval (). J'espère que ça aide :)
Vous pouvez placer vos fonctions dans des variables globales, mais il est préférable de simplement transformer votre script d’outils en un module. Ce n'est vraiment pas trop difficile - attachez simplement votre API publique à l'objet exports
. Jetez un coup d'œil à Comprendre le module d'exportation de Node.js pour plus de détails.
Essayez cet exemple de code complet. Vous devez inclure ce fichier à l'aide de la méthode require
dans app.js
où vous souhaitez inclure les fonctions d'un autre fichier ex main.js
, et ce fichier doit exposer les fonctions spécifiées comme dans l'exemple ci-dessous.
app.js
const mainFile= require("./main.js")
var x = mainFile.add(2,4) ;
console.log(x);
var y = mainFile.multiply(2,5);
console.log(y);
main.js
const add = function(x, y){
return x+y;
}
const multiply = function(x,y){
return x*y;
}
module.exports ={
add:add,
multiply:multiply
}
sortie
6
10
Cela a fonctionné avec moi comme suit ....
Lib1.js
//Any other private code here
// Code you want to export
exports.function1 = function1 (params) {.......};
exports.function2 = function2 (params) {.......};
// Again any private code
maintenant dans le fichier Main.js vous devez inclure Lib1.js
var mylib = requires('lib1.js');
mylib.function1(params);
mylib.function2(params);
N'oubliez pas de placer le fichier Lib1.js dans le dossier node_modules .
app.js
let { func_name } = require('path_to_tools.js');
func_name(); //function calling
tools.js
let func_name = function() {
...
//function body
...
};
module.exports = { func_name };
define({
"data": "XYZ"
});
var fs = require("fs");
var vm = require("vm");
function include(path, context) {
var code = fs.readFileSync(path, 'utf-8');
vm.runInContext(code, vm.createContext(context));
}
// Include file
var customContext = {
"define": function (data) {
console.log(data);
}
};
include('./fileToInclude.js', customContext);
Vous pouvez simplement require('./filename')
.
Par exemple.
// file: index.js
var express = require('express');
var app = express();
var child = require('./child');
app.use('/child', child);
app.get('/', function (req, res) {
res.send('parent');
});
app.listen(process.env.PORT, function () {
console.log('Example app listening on port '+process.env.PORT+'!');
});
// file: child.js
var express = require('express'),
child = express.Router();
console.log('child');
child.get('/child', function(req, res){
res.send('Child2');
});
child.get('/', function(req, res){
res.send('Child');
});
module.exports = child;
Veuillez noter que:
C'est la meilleure façon que j'ai créée jusqu'à présent.
var fs = require('fs'),
includedFiles_ = {};
global.include = function (fileName) {
var sys = require('sys');
sys.puts('Loading file: ' + fileName);
var ev = require(fileName);
for (var prop in ev) {
global[prop] = ev[prop];
}
includedFiles_[fileName] = true;
};
global.includeOnce = function (fileName) {
if (!includedFiles_[fileName]) {
include(fileName);
}
};
global.includeFolderOnce = function (folder) {
var file, fileName,
sys = require('sys'),
files = fs.readdirSync(folder);
var getFileName = function(str) {
var splited = str.split('.');
splited.pop();
return splited.join('.');
},
getExtension = function(str) {
var splited = str.split('.');
return splited[splited.length - 1];
};
for (var i = 0; i < files.length; i++) {
file = files[i];
if (getExtension(file) === 'js') {
fileName = getFileName(file);
try {
includeOnce(folder + '/' + file);
} catch (err) {
// if (ext.vars) {
// console.log(ext.vars.dump(err));
// } else {
sys.puts(err);
// }
}
}
}
};
includeFolderOnce('./extensions');
includeOnce('./bin/Lara.js');
var lara = new Lara();
Vous devez toujours indiquer ce que vous voulez exporter
includeOnce('./bin/WebServer.js');
function Lara() {
this.webServer = new WebServer();
this.webServer.start();
}
Lara.prototype.webServer = null;
module.exports.Lara = Lara;
Vous aimez avoir un fichier abc.txt
et beaucoup plus?
Créez 2 fichiers: fileread.js
et fetchingfile.js
, puis écrivez ce code dans fileread.js
:
function fileread(filename) {
var contents= fs.readFileSync(filename);
return contents;
}
var fs = require("fs"); // file system
//var data = fileread("abc.txt");
module.exports.fileread = fileread;
//data.say();
//console.log(data.toString());
}
Dans fetchingfile.js
, écrivez ce code:
function myerror(){
console.log("Hey need some help");
console.log("type file=abc.txt");
}
var ags = require("minimist")(process.argv.slice(2), { string: "file" });
if(ags.help || !ags.file) {
myerror();
process.exit(1);
}
var hello = require("./fileread.js");
var data = hello.fileread(ags.file); // importing module here
console.log(data.toString());
Maintenant, dans un terminal: $ node fetchingfile.js --file = abc.txt
Vous transmettez le nom de fichier en tant qu'argument. De plus, incluez tous les fichiers dans readfile.js
au lieu de le transmettre.
Merci
J'étais aussi à la recherche d'une option pour inclure du code sans écrire de modules, resp. utilisez les mêmes sources autonomes testées d'un projet différent pour un service Node.js - et la réponse de jmparatte l'a fait pour moi.
L'avantage est que vous ne polluez pas l'espace de noms, je n'ai pas de problème avec "use strict";
et cela fonctionne bien.
Voici un exemple complet:
"use strict";
(function(){
var Foo = function(e){
this.foo = e;
}
Foo.prototype.x = 1;
return Foo;
}())
"use strict";
const fs = require('fs');
const path = require('path');
var SampleModule = module.exports = {
instAFoo: function(){
var Foo = eval.apply(
this, [fs.readFileSync(path.join(__dirname, '/lib/foo.js')).toString()]
);
var instance = new Foo('bar');
console.log(instance.foo); // 'bar'
console.log(instance.x); // '1'
}
}
J'espère que cela a été utile en quelque sorte.
Une autre méthode lors de l’utilisation de framework node.js et express.js
var f1 = function(){
console.log("f1");
}
var f2 = function(){
console.log("f2");
}
module.exports = {
f1 : f1,
f2 : f2
}
stocker ceci dans un fichier js nommé s et dans la statique du dossier
Maintenant pour utiliser la fonction
var s = require('../statics/s');
s.f1();
s.f2();
J'ai mis au point une méthode assez rudimentaire pour gérer cela pour les modèles HTML. De la même manière que PHP <?php include("navigation.html"); ?>
server.js
var fs = require('fs');
String.prototype.filter = function(search,replace){
var regex = new RegExp("{{" + search.toUpperCase() + "}}","ig");
return this.replace(regex,replace);
}
var navigation = fs.readFileSync(__dirname + "/parts/navigation.html");
function preProcessPage(html){
return html.filter("nav",navigation);
}
var express = require('express');
var app = express();
// Keep your server directory safe.
app.use(express.static(__dirname + '/public/'));
// Sorta a server-side .htaccess call I suppose.
app.get("/page_name/",function(req,res){
var html = fs.readFileSync(__dirname + "/pages/page_name.html");
res.send(preProcessPage(html));
});
nom_page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>NodeJS Templated Page</title>
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="/css/font-awesome.min.css">
<!-- Scripts Load After Page -->
<script type="text/javascript" src="/js/jquery.min.js"></script>
<script type="text/javascript" src="/js/tether.min.js"></script>
<script type="text/javascript" src="/js/bootstrap.min.js"></script>
</head>
<body>
{{NAV}}
<!-- Page Specific Content Below Here-->
</body>
</html>
navigation.html
<nav></nav>
Résultat de la page chargée
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>NodeJS Templated Page</title>
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="/css/font-awesome.min.css">
<!-- Scripts Load After Page -->
<script type="text/javascript" src="/js/jquery.min.js"></script>
<script type="text/javascript" src="/js/tether.min.js"></script>
<script type="text/javascript" src="/js/bootstrap.min.js"></script>
</head>
<body>
<nav></nav>
<!-- Page Specific Content Below Here-->
</body>
</html>
Si vous souhaitez tirer parti de l’architecture de plusieurs processeurs et microservices, accélérez les choses ... Utilisez des RPC par rapport aux processus définis.
Cela semble complexe, mais c'est simple si vous utilisez octopus .
Voici un exemple:
sur tools.js ajouter:
const octopus = require('octopus');
var rpc = new octopus('tools:tool1');
rpc.over(process, 'processRemote');
var sum = rpc.command('sum'); // This is the example tool.js function to make available in app.js
sum.provide(function (data) { // This is the function body
return data.a + data.b;
});
sur app.js, ajoutez:
const { fork } = require('child_process');
const octopus = require('octopus');
const toolprocess = fork('tools.js');
var rpc = new octopus('parent:parent1');
rpc.over(toolprocess, 'processRemote');
var sum = rpc.command('sum');
// Calling the tool.js sum function from app.js
sum.call('tools:*', {
a:2,
b:3
})
.then((res)=>console.log('response : ',rpc.parseResponses(res)[0].response));
divulgation - je suis l'auteur de poulpe, et construit si pour un cas d'utilisation similaire de la mienne, puisque je ne pouvais pas trouver de bibliothèques légères.
Pour transformer des "outils" en un module, je ne vois pas du tout mal. Malgré toutes les autres réponses, je recommanderais quand même l’utilisation de module.exports:
//util.js
module.exports = {
myFunction: function () {
// your logic in here
let message = "I am message from myFunction";
return message;
}
}
Maintenant, nous devons affecter ces exportations à la portée globale (dans votre application | index | server.js)
var util = require('./util');
Maintenant, vous pouvez vous référer et appeler fonction comme:
//util.myFunction();
console.log(util.myFunction()); // prints in console :I am message from myFunction