javascript - I Node.js, hur gör jag för att "inkludera" funktioner från mina andra filer?


Säg att jag har en fil som heter app.js. Ganska enkelt:

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

Vad händer om jag har funktioner inne i "tools.js". Hur skulle jag importera dem för att använda i apps.js?

Eller…ska jag förvandla "tools" till en modul och sedan kräva den? << verkar svårt, jag föredrar att göra den grundläggande importen av tools.js-filen.

Svar #1

Du kan kräva vilken js-fil som helst, du behöver bara deklarera vad du vill exponera.

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

var zemba = function () {
}

Och i din app-fil:

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

Svar #2

Om du, trots alla de andra svaren, fortfarande vill traditionellt inkludera en fil i en node.js-källfil, kan du använda detta:

var fs = require('fs');

// file is included here:
eval(fs.readFileSync('tools.js')+'');
  • Den tomma strängkonkateneringen +'' är nödvändig för att få filinnehållet som en sträng och inte som ett objekt (du kan också använda .toString() om du föredrar det).
  • eval() kan inte användas inne i en funktion och måste anropas i globalt omfång, annars kommer inga funktioner eller variabler att vara tillgängliga (dvs. du kan inte skapa en include()-hjälpfunktion eller något liknande).

Observera att detta i de flesta fall är dålig praxis och du bör istället skriva en modul. Det finns dock sällsynta situationer där förorening av ditt lokala kontext/namnrymd är vad du verkligen vill.

Uppdatering 2015-08-06

Observera också att detta inte kommer att fungera med "use strict"; (när du är i "strict-läge") eftersom funktioner och variabler definierade i den "importerade" filen inte kan nås av koden som gör importen. Strict-läge inför vissa regler definierade av nyare versioner av språkstandarden. Detta kan vara ytterligare en anledning att undvika lösningen som beskrivs här.

Svar #3

Du behöver inga nya funktioner eller nya moduler. Du behöver helt enkelt köra modulen du anropar om du inte vill använda namnrymden.

i tools.js

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

i app.js

eller i någon annan .js som myController.js :

istället för

var tools=require('tools.js') vilket tvingar oss att använda ett namnrymd och kalla verktyg som tools.sum(1,2);

vi kan helt enkelt kalla

require('tools.js')();

och sedan

sum(1,2);

i mitt fall har jag en fil med kontroller ctrls.js

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

och jag kan använda Categories i varje sammanhang som offentlig klass efter require('ctrls.js')()

Svar #4

Skapa två js-filer

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

Huvud-js-fil

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

Konsolutdata

Value: 30

Svar #5

skapa två filer t.ex. app.js och tools.js

app.js

const tools= require("./tools.js")


var x = tools.add(4,2) ;

var y = tools.subtract(4,2);


console.log(x);
console.log(y);

verktyg.js

 const add = function(x, y){
        return x+y;
    }
 const subtract = function(x, y){
            return x-y;
    }
    
    module.exports ={
        add,subtract
    }

utdata

6
2

Svar #6

Här är en enkel och tydlig förklaring:

Server.js innehåll:

// 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 innehåll:

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

Svar #7

Jag letade också efter en NodeJS 'include'-funktion och jag kollade lösningen som föreslogs av Udo G - se meddelande https://stackoverflow.com/a/8744519/2979590. Hans kod fungerar inte med mina inkluderade JS-filer. Till slut löste jag problemet på följande sätt:

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

Självklart, det hjälper.

Svar #8

Skapa två JavaScript-filer. T.ex. import_functions.js och main.js

1.) import_functions.js

// Declaration --------------------------------------

 module.exports =
   {
     add,
     subtract
     // ...
   }


// Implementation ----------------------------------

 function add(x, y)
 {
   return x + y;
 }

 function subtract(x, y)
 {
   return x - y;
 }
    

// ...

2.) main.js

// include ---------------------------------------

const sf= require("./import_functions.js")

// use -------------------------------------------

var x = sf.add(4,2);
console.log(x);

var y = sf.subtract(4,2);
console.log(y);

    

utdata

6
2

Svar #9

Vm-modulen i Node.js ger möjlighet att köra JavaScript-kod inom den aktuella kontexten (inklusive det globala objektet). Se http://nodejs.org/docs/latest/api/vm.html#vm_vm_runinthiscontext_code_filename

Observera att det, från och med idag, finns en bugg i vm-modulen som förhindrar att runInThisContext fungerar korrekt när det anropas från ett nytt sammanhang. Detta spelar endast roll om ditt huvudprogram kör kod inom ett nytt sammanhang och sedan den koden anropar runInThisContext. Se https://github.com/joyent/node/issues/898

Tyvärr fungerar inte det med(global)-tillvägagångssätt som Fernando föreslog för namngivna funktioner som "function foo() {}"

Kort sagt, här är en include()-funktion som fungerar för mig:

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

Svar #10

säg att vi vill anropa funktionen ping() och add(30,20) som finns i lib.js-filen från 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
    }

Svar #11

Udo G. sa:

  • eval() kan inte användas inne i en funktion och måste kallas i det globala omfånget, annars kommer inga funktioner eller variabler vara tillgängliga (d.v.s. du kan inte skapa en include()-hjälpfunktion eller något liknande).

Han har rätt, men det finns ett sätt att påverka det globala omfånget från en funktion. Förbättrar hans exempel:

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

include('somefile_with_some_declarations.js');

// the declarations are now accessible here.

Hoppas det hjälper.

Svar #12

Det fungerade för mig på följande sätt....

Lib1.js

//Any other private code here 

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

// Again any private code

nu i Main.js-filen behöver du inkludera Lib1.js

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

Kom ihåg att lägga Lib1.js i node_modules-mappen.

Svar #13

Ett annat sätt att göra detta, enligt min åsikt, är att köra allt i lib-filen när du anropar require()-funktionen med hjälp av (function(/* saker här */){})(); att göra detta kommer att göra alla dessa funktioner globala, exakt som eval()-lösningen

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

Och sedan i din huvudkod kan du kalla på dina funktioner med namn som:

main.js

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

Kommer att göra detta utskrift

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

Var uppmärksam på undefined när du kallar på mitt object.funcFour(), det kommer att vara samma om du laddar med eval(). Hoppas det hjälper :)

Svar #14

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

Svar #15

Jag vill bara tillägga, ifall du bara behöver vissa funktioner importerade från din tools.js, så kan du använda en destruktureringsuppdragning som stöds i node.js sedan version 6.4 - se node.green.

Exempel: (båda filerna finns i samma mapp)

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

output: true

Detta förhindrar också att du tilldelar dessa funktioner som egenskaper till ett annat objekt, som är fallet i följande (vanliga) tilldelning:

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

där du behöver kalla tools.isEven(10).

OBS:

Glöm inte att prefixa ditt filnamn med rätt sökväg - även om båda filerna finns i samma mapp, måste du prefixa med ./

Från Node.js-dokumentationen:

Utan ett ledande '/' , './' eller '../' för att ange en fil, måste modulen antingen vara en kärnmodul eller laddas från en node_modules-mapp.

Relaterade artiklar