it-swarm.com.de

Wie füge ich in Node.js Funktionen aus meinen anderen Dateien ein?

Nehmen wir an, ich habe eine Datei namens app.js. Ziemlich einfach:

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);

Was ist, wenn ich Funktionen in "tools.js" habe. Wie importiere ich sie zur Verwendung in apps.js?

Oder ... soll ich "Werkzeuge" in ein Modul umwandeln und dann verlangen? << scheint schwierig zu sein, ich mache den grundlegenden Import der tools.js-Datei.

789
TIMEX

Sie können eine beliebige js-Datei anfordern. Sie müssen nur angeben, was Sie veröffentlichen möchten.

// tools.js
// ========
module.exports = {
  foo: function () {
    // whatever
  },
  bar: function () {
    // whatever
  }
};

var zemba = function () {
}

Und in deiner App-Datei:

// app.js
// ======
var tools = require('./tools');
console.log(typeof tools.foo); // => 'function'
console.log(typeof tools.bar); // => 'function'
console.log(typeof tools.zemba); // => undefined
1189
masylum

Wenn Sie trotz aller anderen Antworten traditionelleine Datei in eine node.js-Quelldatei aufnehmen möchten, können Sie dies verwenden:

var fs = require('fs');

// file is included here:
eval(fs.readFileSync('tools.js')+'');
  • Die leere Zeichenfolgenverkettung +'' ist erforderlich, um den Dateiinhalt als Zeichenfolge und nicht als Objekt abzurufen (Sie können auch .toString() verwenden, wenn Sie dies vorziehen).
  • Das eval () kann nicht innerhalb einer Funktion verwendet werden undmussinnerhalb des globalen Gültigkeitsbereichs aufgerufen werden, da sonst keine Funktionen oder Variablen verfügbar sind (dh Sie können keine erstellen) include() utility function oder so ähnlich).

Bitte beachten Sie, dass dies in den meisten Fällenschlechte Praxisist und Sie stattdessen schreiben Sie ein Modul . Es gibt jedoch seltene Situationen, in denen die Verschmutzung Ihres lokalen Kontexts/Namespaces das ist, was Sie wirklich wollen.

Update 06.08.2015

Bitte beachten Sie auch, dass dies mit "use strict"; nicht funktioniert (wenn Sie sich in "strenger Modus" befinden), da Funktionen und Variablendefinedin der "importierten" Datei auf die nicht zugegriffen werden kann durch den Code, der den Import ausführt. Im strengen Modus werden einige Regeln durchgesetzt, die in neueren Versionen des Sprachstandards definiert sind. Dies kann ein weiterer Grund sein, umdie hier beschriebene Lösung zu vermeiden.

283
Udo G

Sie benötigen weder neue Funktionen noch neue Module. Sie müssen nur das von Ihnen aufgerufene Modul ausführen, wenn Sie keinen Namespace verwenden möchten.

in tools.js

module.exports = function() { 
    this.sum = function(a,b) { return a+b };
    this.multiply = function(a,b) { return a*b };
    //etc
}

in app.js

oder in anderen .js wie myController.js:

anstatt

var tools = require('tools.js'), die uns zwingt, einen Namespace zu verwenden und Tools wie tools.sum(1,2); aufzurufen.

wir können einfach anrufen

require('tools.js')();

und dann

sum(1,2);

in meinem Fall habe ich eine Datei mit Controllern ctrls.js

module.exports = function() {
    this.Categories = require('categories.js');
}

und ich kann Categories in jedem Kontext als öffentliche Klasse nach require('ctrls.js')() verwenden

161
Nick Panov

Erstellen Sie zwei js-Dateien

// File cal.js
module.exports = {
    sum: function(a,b) {
        return a+b
    },
    multiply: function(a,b) {
        return a*b
    }
};

Haupt-js-Datei

// File app.js
var tools = require("./cal.js");
var value = tools.sum(10,20);
console.log("Value: "+value);

Ausgabe

value: 30
79
Jayaprakash G

Hier ist eine einfache und einfache Erklärung:

Server.js Inhalt:

// 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);

Helpers.js Inhalt:

// '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 () 
{
};
39
Placeholder

Ich habe auch nach einer NodeJS-Include-Funktion gesucht und die von Udo G vorgeschlagene Lösung geprüft - siehe message https://stackoverflow.com/a/8744519/2979590 . Sein Code funktioniert nicht mit meinen mitgelieferten JS-Dateien ... Endlich löste ich das Problem so:

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');

Klar, das hilft.

32
jmparatte

Das vm-Modul in Node.js bietet die Möglichkeit, JavaScript-Code innerhalb des aktuellen Kontexts (einschließlich des globalen Objekts) auszuführen. Siehe http://nodejs.org/docs/latest/api/vm.html#vm_vm_runinthiscontext_code_filename

Beachten Sie, dass es seit heute einen Fehler im vm-Modul gibt, der es runInThisContext vor dem Ausführen des Rechtes beim Aufruf aus einem neuen Kontext verhindert. Dies ist nur von Bedeutung, wenn Ihr Hauptprogramm Code in einem neuen Kontext ausführt und dieser Code dann runInThisContext aufruft. Siehe https://github.com/joyent/node/issues/898

Leider funktioniert der von Fernando vorgeschlagene Ansatz mit (globalem) Ansatz nicht für benannte Funktionen wie "function foo () {}"

Kurz gesagt, hier ist eine include () - Funktion, die für mich funktioniert:

function include(path) {
    var code = fs.readFileSync(path, 'utf-8');
    vm.runInThisContext(code, path);
}
23
Chad Austin

angenommen, wir möchten die Funktion ping () und add (30,20)} aufrufen, die sich in lib.js Datei von 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
    }
22
Dharmesh

Udo G. sagte: 

  • Das eval () kann nicht innerhalb einer Funktion verwendet werden und muss in .__ aufgerufen werden. Der globale Gültigkeitsbereich wird andernfalls keine Funktionen oder Variablen sein zugreifbar (d. h. Sie können keine Dienstprogrammfunktion include () oder ähnliches erstellen).

Er hat recht, aber es gibt eine Möglichkeit, den globalen Geltungsbereich einer Funktion zu beeinflussen. Sein Beispiel verbessern:

function include(file_) {
    with (global) {
        eval(fs.readFileSync(file_) + '');
    };
};

include('somefile_with_some_declarations.js');

// the declarations are now accessible here.

Hoffentlich hilft das.

13
Fernando

Eine andere Möglichkeit, dies zu tun, besteht meiner Meinung nach darin, alles in der lib-Datei auszuführen, wenn Sie die Funktion requir () mit (function (/ * things here * /) {}) () aufrufen. Wenn Sie dies tun, werden alle diese Funktionen global festgelegt, genau wie bei der Lösung 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');
            }
    }
})();

Und dann können Sie Ihre Funktionen in Ihrem Hauptcode über den Namen aufrufen:

main.js

require('./src/lib')
funcOne();
funcThree('Alex');
console.log(name);
console.log(myobject);
console.log(myobject.funcFour());

Werde diese Ausgabe machen

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

Achten Sie auf das undefined, wenn Sie mein object.funcFour () aufrufen. Das Gleiche gilt, wenn Sie mit eval () laden. Ich hoffe es hilft :)

11

Ich möchte nur hinzufügen, falls Sie nur bestimmte Funktionen benötigen, die aus Ihrer tools.js importiert wurden, können Sie ein verwenden. destructuring arrangement , die in node.js seit version 6.4 unterstützt wird - siehe node.green .


Beispiel : (beide Dateien befinden sich im selben Ordner)

tools.js

module.exports = {
    sum: function(a,b) {
        return a + b;
    },
    isEven: function(a) {
        return a % 2 == 0;
    }
};

main.js

const { isEven } = require('./tools.js');

console.log(isEven(10));

Ausgabe: true


Dadurch wird auch vermieden, dass Sie diese Funktionen als Eigenschaften eines anderen Objekts zuweisen, wie dies bei der folgenden (allgemeinen) Zuweisung der Fall ist:

const tools = require('./tools.js');

wo müssen Sie tools.isEven(10) aufrufen.


HINWEIS:

Vergessen Sie nicht, Ihrem Dateinamen den richtigen Pfad voran zu stellen - auch wenn sich beide Dateien im selben Ordner befinden, müssen Sie ./ Voranstellen.

Von Node.js docs :

Ohne ein vorangestelltes '/', './' oder '../' zur Angabe einer Datei muss das Modul entweder ein Kernmodul sein oder wird aus einem node_modules-Ordner geladen.

9
Kristianmitk

Sie können Ihre Funktionen in globale Variablen einfügen, aber es ist besser, Ihr Toolskript einfach in ein Modul umzuwandeln. Es ist wirklich nicht zu schwer - hängen Sie einfach Ihre öffentliche API an das exports-Objekt an. Werfen Sie einen Blick auf Das Exportmodul von Node.js , um mehr zu erfahren.

9
Jimmy Cuadra

Versuchen Sie diesen vollständigen Beispielcode. Sie müssen diese Datei mit der require -Methode in app.js einschließen, wobei Sie die Funktionen einer anderen Datei außer main.js einschließen möchten.

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
}

ausgabe

6
10
6
YouBee

Es hat bei mir wie folgt geklappt .... 

Lib1.js

//Any other private code here 

// Code you want to export
exports.function1 = function1 (params) {.......};
exports.function2 = function2 (params) {.......};

// Again any private code

in der Datei Main.js muss jetzt Lib1.js eingefügt werden

var mylib = requires('lib1.js');
mylib.function1(params);
mylib.function2(params);

Denken Sie daran, die Datei Lib1.js im Ordner node_modules abzulegen.

6
M.Hefny

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 };
4
Ashish Duklan

Fügen Sie die Datei ein und führen Sie sie in einem bestimmten (nicht globalen) Kontext aus

fileToInclude.js

define({
    "data": "XYZ"
});

main.js

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);
3
user11153

Sie können einfach nur require('./filename').

Z.B.

// 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;

Bitte beachte, dass:

  1. sie können PORT nicht in der untergeordneten Datei abhören. Nur das übergeordnete Expressmodul verfügt über einen PORT-Listener
  2. Kind verwendet 'Router', keine übergeordnete Express-Moudle.
2
Weijing Lin

Dies ist der beste Weg, den ich bisher geschaffen habe.

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();

Sie müssen noch informieren, was Sie exportieren möchten

includeOnce('./bin/WebServer.js');

function Lara() {
  this.webServer = new WebServer();
  this.webServer.start();
}

Lara.prototype.webServer = null;

module.exports.Lara = Lara;

Als hätten Sie eine Datei abc.txt und viele mehr? 

Erstellen Sie 2 Dateien: fileread.js und fetchingfile.js und schreiben Sie dann in fileread.js diesen Code:

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());
}

In fetchingfile.js schreibe diesen 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());

Jetzt in einem Terminal: $ node fetchingfile.js --file = abc.txt

Sie übergeben den Dateinamen als Argument und schließen alle Dateien in readfile.js ein, anstatt sie zu übergeben.

Vielen Dank

2
Gajender Singh

Ich war auch auf der Suche nach einer Möglichkeit, Code einzuschließen, ohne Module zu schreiben. Verwenden Sie dieselben getesteten Standalone-Quellen aus einem anderen Projekt für einen Node.js-Dienst - und die Antwort von jmparatte hat dies für mich getan.

Der Vorteil ist, dass Sie den Namespace nicht verschmutzen. Ich habe keine Probleme mit "use strict"; und es funktioniert gut.

Hier ein full Beispiel:

Skript zum Laden von - /lib/foo.js

"use strict";

(function(){

    var Foo = function(e){
        this.foo = e;
    }

    Foo.prototype.x = 1;

    return Foo;

}())

SampleModule - index.js

"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'
    }

}

Hoffe, das war irgendwie hilfreich.

1
zyexal

Eine andere Methode bei der Verwendung von node.js und express.js-Framework

var f1 = function(){
   console.log("f1");
}
var f2 = function(){
   console.log("f2");
}

module.exports = {
   f1 : f1,
   f2 : f2
}

speichern Sie dies in einer js-Datei mit dem Namen s und im Ordner statics

Nun nutzen Sie die Funktion

var s = require('../statics/s');
s.f1();
s.f2();
1
suku

Ich habe eine ziemlich grobe Methode gefunden, wie man dies für HTML-Templates schafft. Ähnlich wie 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));
});

Seitenname.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>

Geladenes Seitenergebnis

<!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>
1
Matthew D Auld

Wenn Sie mehrere CPUs und Microservice-Architekturen nutzen möchten, um die Dinge zu beschleunigen ... Verwenden Sie RPCs über verzweigte Prozesse.

Klingt komplex, aber es ist einfach, wenn Sie octopus verwenden.

Hier ist ein Beispiel:

auf tools.js hinzufügen:

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;
});

fügen Sie in app.js Folgendes hinzu:

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));

disclosure - Ich bin der Autor von Octopus und habe eine ähnliche Anwendung entwickelt, da ich keine leichten Bibliotheken finden konnte.

0
DhavalW

Um "Werkzeuge" in ein Modul zu verwandeln, sehe ich überhaupt nichts. Trotz aller anderen Antworten würde ich die Verwendung von module.exports weiterhin empfehlen:

//util.js
module.exports = {
   myFunction: function () {
   // your logic in here
   let message = "I am message from myFunction";
   return message; 
  }
}

Jetzt müssen wir diese Exporte dem globalen Bereich zuordnen (in Ihrer app | index | server.js)

var util = require('./util');

Jetzt können Sie die Funktion beziehen und aufrufen als:

//util.myFunction();
console.log(util.myFunction()); // prints in console :I am message from myFunction 
0
StefaDesign