javascript - tutorial - require(' express ') in node js




In Node.js, come faccio a "includere" le funzioni dai miei altri file? (16)

Includi il file ed eseguilo in un determinato contesto (non globale)

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

Diciamo che ho un file chiamato app.js. Abbastanza semplice:

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

Cosa succede se ho una funzione all'interno di "tools.js". Come posso importarli per l'uso in apps.js?

Oppure ... dovrei trasformare "strumenti" in un modulo e quindi richiederlo? << sembra difficile, preferisco fare l'importazione di base del file tools.js.


App.js:

var mymouldle = require("C:/Users/Yourname/tools.js")
//replace C:/Users/Yourname/tools.js with the path to your tools.js

NOTA: il file deve iniziare con C: o D: o E: altrimenti Node.js pensa che il mouldle si trovi nella cartella dei mouldles del nodo


Crea due file js

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

File js principale

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

Produzione

value: 30

Ecco una spiegazione semplice e semplice:

Contenuto Server.js:

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

Contenuto Helpers.js:

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

Ho trovato un metodo piuttosto grezzo di gestione di questo per i template HTML. Analogamente a PHP <?php include("navigation.html"); ?> <?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));
});

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

Risultato della pagina caricata

<!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>

Il modulo vm in Node.js offre la possibilità di eseguire codice JavaScript all'interno del contesto corrente (incluso l'oggetto globale). Vedi http://nodejs.org/docs/latest/api/vm.html#vm_vm_runinthiscontext_code_filename

Nota che, ad oggi, c'è un bug nel modulo vm che previene il runInThisContext dal fare il diritto quando viene invocato da un nuovo contesto. Ciò è importante solo se il tuo programma principale esegue il codice all'interno di un nuovo contesto e quindi il codice chiama runInThisContext. Vedi https://github.com/joyent/node/issues/898

Purtroppo, l'approccio (globale) suggerito da Fernando non funziona per funzioni denominate come "function foo () {}"

In breve, ecco una funzione include () che funziona per me:

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

Puoi mettere le tue funzioni in variabili globali, ma è meglio fare semplicemente girare lo script degli strumenti in un modulo. Non è davvero troppo difficile - basta allegare la tua API pubblica all'oggetto exports . Dai un'occhiata al modulo delle esportazioni di Node.js per ulteriori dettagli.


Puoi richiedere qualsiasi file js, devi solo dichiarare ciò che vuoi esporre.

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

var zemba = function () {
}

E nel tuo file dell'app:

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

Questo è il modo migliore che ho creato finora.

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

Hai ancora bisogno di informare ciò che vuoi esportare

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

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

Lara.prototype.webServer = null;

module.exports.Lara = Lara;

Se vuoi approfittare di più CPU e architettura di Microservice, per velocizzare le cose ... Usa gli RPC su processi biforcati.

Sembra complesso, ma è semplice se usi il octopus .

Ecco un esempio:

su tools.js aggiungi:

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

su app.js, aggiungi:

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 - Sono l'autore di octopus, e costruito per un mio simile pacchetto, dal momento che non sono riuscito a trovare alcuna libreria leggera.


Stavo anche cercando un'opzione per includere il codice senza scrivere moduli, resp. utilizzare le stesse sorgenti autonome testate da un progetto diverso per un servizio Node.js - e la risposta di lo ha fatto per me.

Il vantaggio è che non si inquina lo spazio dei nomi, non ho problemi con "use strict"; e funziona bene.

Ecco un esempio completo :

Script da caricare - /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'
    }

}

Spero che questo sia stato utile in qualche modo.


Stavo anche cercando una funzione 'include' di NodeJS e ho controllato la soluzione proposta da Udo G - vedi messaggio https://.com/a/8744519/2979590 . Il suo codice non funziona con i miei file JS inclusi. Alla fine ho risolto il problema in questo modo:

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

Certo, questo aiuta.


Un altro metodo quando si utilizza il framework node.js e express.js

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

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

memorizzarlo in un file js denominato s e nella cartella statica

Ora per usare la funzione

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

Un altro modo per farlo a mio parere è eseguire tutto nel file lib quando chiamate funzione require () usando (function (/ * things here * /) {}) (); facendo questo si renderanno globali tutte queste funzioni, esattamente come la soluzione 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');
            }
    }
})();

E poi nel tuo codice principale puoi chiamare le tue funzioni per nome come:

main.js

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

Farà questa uscita

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

Prestare attenzione al non definito quando si chiama il mio oggetto.funcFour () , sarà lo stesso se si carica con eval () . Spero che sia d'aiuto :)


diciamo che vogliamo chiamare function ping () e add (30,20) che è nel file lib.js da 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
    }

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






node.js