En Node.js, ¿cómo "incluyo" funciones de mis otros archivos?

Digamos que tengo un archivo llamado app.js. Bastante 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);

¿Qué pasa si tengo funciones dentro de "tools.js"? ¿Cómo los importaría para usarlos en apps.js?

O ... ¿se supone que debo convertir "herramientas" en un módulo y luego requerirlo? << parece difícil, prefiero hacer la importación básica del archivo tools.js.

preguntado el 26 de abril de 11 a las 20:04

Lo que me desconcertó aquí fue requireing una carpeta en el mismo directorio en Windows. Tienes que usar direcciones de estilo Unix: ./mydir en lugar de simplemente viejo mydir. -

Creé un módulo para importar scripts, exportar a un archivo e incluir un módulo desde fuera node_modules carpeta. npmjs.com/package/node-importación Espero que pueda ayudar. ¡Gracias! -

25 Respuestas

Puede requerir cualquier archivo js, ​​solo necesita declarar lo que desea exponer.

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

var zemba = function () {
}

Y en el archivo de su aplicación:

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

respondido 06 mar '17, 23:03

+1 Bien hecho, incluso limita el código importado a su propio espacio de nombres. Tendré que tomar nota de esto para más tarde. - Evan Solla

Me pregunto si es posible importar scripts externos. require("http://javascript-modules.googlecode.com/svn/functionChecker.js") no parece importar el módulo correctamente. ¿Existe alguna otra forma de importar scripts externos? - anderson verde

¿Y qué pasa si tengo que pasar la variable a la función Like, bar: function (a, b) {// algún código} - Nishutosh Sharma

Como está exponiendo propiedades, usaría exportaciones en lugar de module.exports. Para exportaciones vs module.exports: stackoverflow.com/questions/5311334/… - Fincas

cómo llamar a la función bar (), dentro de la función foo (), significa cómo acceder a una función dentro de otra - pitu

Si, a pesar de todas las otras respuestas, todavía desea tradicionalmente incluir un archivo en un archivo fuente de node.js, puede usar esto:

var fs = require('fs');

// file is included here:
eval(fs.readFileSync('tools.js')+'');
  • La concatenación de cadenas vacías +'' es necesario para obtener el contenido del archivo como una cadena y no como un objeto (también puede usar .toString() si tu prefieres).
  • El eval () no se puede utilizar dentro de una función y debe: ser llamado dentro del alcance global; de lo contrario, no se podrá acceder a funciones o variables (es decir, no se puede crear un include() función de utilidad o algo así).

Tenga en cuenta que en la mayoría de los casos esto es mala práctica y deberías en su lugar escribir un módulo. Sin embargo, hay situaciones raras en las que lo que realmente desea es la contaminación de su contexto / espacio de nombres local.

Actualización 2015-08-06

Tenga en cuenta también que esto no funcionará con "use strict"; (cuando estás en "Modo estricto") porque funciones y variables se define en el archivo "importado" no se puede acceder por el código que realiza la importación. El modo estricto aplica algunas reglas definidas por versiones más recientes del estándar de lenguaje. Esta puede ser otra razón para evitar la solución descrita aquí.

contestado el 23 de mayo de 17 a las 12:05

Genial, esto es útil para colocar rápidamente JS libs diseñadas para el lado del cliente en una aplicación node.js sin la necesidad de mantener una bifurcación estilo Node. - Kos

Acabo de responder la pregunta original, que trata de incluir código, no de escribir módulos. El primero puede tienen ventajas en determinadas situaciones. Además, su suposición sobre require es incorrecta: el código ciertamente está evaluado, pero permanece en su propio espacio de nombres y no tiene forma de "contaminar" el espacio de nombres del contexto de llamada, por lo tanto, debe evaluarlo usted mismo. En la mayoría de los casos, utilizando el método descrito en mi respuesta es una mala práctica pero no soy yo quien debería decidir si es para TIMEX. - udo g

@EvanPlaice: ¿tienes una sugerencia mejor? que en realidad responde a la pregunta? Si necesita incluir un archivo que no es un modulo, ¿tienes un enfoque mejor que este? - jalf

A veces, cuando es necesario incluir, y a veces requiere, son dos conceptos fundamentalmente diferentes en la mayoría de los lenguajes de programación, Node JS también. La capacidad de incluir js en su lugar debería ser parte de Node para ser honesto, pero evaluarlo es esencialmente una solución decente. Voto a favor. - J. Martín

Tenga en cuenta que es incompatible con uso estricto - como uso estricto restringirá el uso de eval bloqueando la introducción de nuevas variables a través de eval, etc. - timbó

No necesita nuevas funciones ni nuevos módulos. Simplemente necesita ejecutar el módulo al que está llamando si no desea usar el espacio de nombres.

en tools.js

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

en app.js

o en cualquier otro .js como myController.js:

en lugar de

var tools = require('tools.js') que nos obligan a utilizar un espacio de nombres y llamar a herramientas como tools.sum(1,2);

simplemente podemos llamar

require('tools.js')();

y entonces

sum(1,2);

en mi caso tengo un archivo con controladores ctrls.js

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

y puedo usar Categories en todos los contextos como clase pública después require('ctrls.js')()

Respondido el 20 de junio de 20 a las 10:06

¿Cómo es que esto no tiene más +1? Esta es una solución real a lo que plantea la pregunta (aunque no la "oficial"). También es un millón de veces más fácil de depurar que eval () porque el nodo puede dar una pila de llamadas útil en lugar de apuntar al archivo real en lugar de simplemente indefinido. - user3413723

Tenga en cuenta que no puede "usar el modo 'estricto" en el módulo importado. - David

@Nick Panov: ¡brillante! Vale la pena señalar que esto funciona porque this en una función es el alcance global cuando se llama a la función directamente (sin vinculación de ninguna manera). - udo g

esto acaba de cambiar mi vida, no es broma: tenía un archivo de más de 1000 líneas que no podía dividir porque las variables de los diferentes métodos están todas interrelacionadas y necesitarían que los requisitos estén todos en el mismo alcance ... require('blah.js')(); debería permitirme importarlos todos en el mismo alcance !!! ¡¡¡Gracias!!! - Sam Johnson

¡Este es un gran consejo! Advertencia: si declara la función module.exports usando la sintaxis de acceso directo () => {} en lugar de la declaración de función estándar () {}, falla. ¡Me tomó una hora descubrir dónde estaba el problema! (Las funciones de flecha no tienen su propia propiedad 'this': desarrollador.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) - ryan griggs

Crea dos archivos js

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

Archivo js principal

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

Salida de consola

Value: 30

Respondido 04 Oct 19, 18:10

la función declarada en otro archivo ¿hay alguna forma de identificar el tipo, me refiero al codificar cuando presiono? ¿Podrá algún ide entender qué tipo de objeto es? Sólo inténtalo

crear dos archivos, por ejemplo app.js y tools.js

aplicación.js

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


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

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


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

herramientas.js

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

salida

6
2

respondido 31 mar '21, 10:03

gracias estaba usando la sintaxis de ES6 - Gothburz

Aquí hay una explicación simple y llana:

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

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

respondido 15 nov., 14:09

También estaba buscando una función 'incluir' NodeJS y verifiqué la solución propuesta por udo g - ver mensaje https://stackoverflow.com/a/8744519/2979590. Su código no funciona con mis archivos JS incluidos. Finalmente resolví el problema así:

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

Claro, eso ayuda.

contestado el 23 de mayo de 17 a las 13:05

Entiendo lo feo que es este truco, pero seguro que me ayudó. - lindhe

Nuevo en Node. Me parece una locura, esto es lo que se requiere simplemente para insertar algunos JS, pero esta fue la única solución que funcionó para mí, gracias. Tantas respuestas que mencionan módulos, increíble. - Nomas Prime

El módulo vm en Node.js brinda la capacidad de ejecutar código JavaScript dentro del contexto actual (incluido el objeto global). Ver http://nodejs.org/docs/latest/api/vm.html#vm_vm_runinthiscontext_code_filename

Tenga en cuenta que, a partir de hoy, hay un error en el módulo vm que impide que runInThisContext haga lo correcto cuando se invoca desde un nuevo contexto. Esto solo importa si su programa principal ejecuta código dentro de un nuevo contexto y luego ese código llama a runInThisContext. Ver https://github.com/joyent/node/issues/898

Lamentablemente, el enfoque with (global) que sugirió Fernando no funciona para funciones con nombre como "function foo () {}"

En resumen, aquí hay una función include () que me funciona:

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

Respondido el 26 de junio de 12 a las 21:06

Encontré vm.runInThisContext en otra respuesta SO, y lo había estado usando para incluir archivos de código Javascript "vanilla". Luego, sin embargo, traté de usarlo para incluir código que dependía de la funcionalidad del nodo (por ejemplo, "var fs = require ('fs')"), y no funcionó. Sin embargo, en ese caso, las soluciones "eval" que se indican en un par de respuestas sí funcionan. - Dexígeno

Pensando en esto un poco más, cuando comience a necesitar incluir código que depende de la funcionalidad del nodo, probablemente sea el momento de escribir un módulo, aunque la solución de evaluación podría ser el primer paso en ese proceso: Dexígeno

decir que queremos llamar a la función silbido() y añadir (30,20) Qué esta en lib.js archivo de principal.js

principal.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
    }

Respondido 03 Feb 16, 17:02

Esto funciona, pero ¿no se supone que debemos usar la sintaxis de los módulos al incluir scripts? - kokodoko

Cree dos archivos JavaScript. P.ej import_functions.js y 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.) principal.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);

    

salida

6
2

Respondido el 18 de junio de 21 a las 14:06

Udo G. dijo:

  • El eval () no se puede usar dentro de una función y se debe llamar dentro del alcance global, de lo contrario no se podrá acceder a funciones o variables (es decir, no se puede crear una función de utilidad include () o algo así).

Tiene razón, pero hay una forma de afectar el alcance global desde una función. Mejorando su ejemplo:

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

include('somefile_with_some_declarations.js');

// the declarations are now accessible here.

Espero que ayude.

Respondido el 05 de enero de 12 a las 14:01

Otra forma de hacer esto, en mi opinión, es ejecutar todo en el archivo lib cuando llamas requerir () función usando (función (/ * cosas aquí * /) {}) (); Hacer esto hará que todas estas funciones alcancen un alcance global, exactamente como el eval () solución

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

Y luego, en su código principal, puede llamar a sus funciones por nombre como:

principal.js

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

Hará esta salida

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

Preste atención a la indefinido cuando llamas a mi object.funcFour (), será lo mismo si carga con eval (). Espero eso ayude :)

Respondido el 27 de enero de 17 a las 13:01

aplicación.js

let { func_name } = require('path_to_tools.js');
func_name();    //function calling

herramientas.js

let func_name = function() {
    ...
    //function body
    ...
};

module.exports = { func_name };

Respondido 08 Oct 18, 15:10

Funcionó conmigo como el siguiente ...

Lib1.js

//Any other private code here 

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

// Again any private code

ahora en el Principal.js archivo que necesita incluir Lib1.js

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

Recuerde poner Lib1.js en carpeta node_modules.

Respondido el 14 de junio de 19 a las 17:06

Puede poner sus funciones en variables globales, pero es una mejor práctica simplemente convertir el script de sus herramientas en un módulo. Realmente no es demasiado difícil, simplemente adjunte su API pública a la exports objeto. Echa un vistazo a Comprender el módulo de exportaciones de Node.js para más detalles.

respondido 29 nov., 16:17

Un ejemplo es mejor que un enlace: tno2007

Solo quiero agregar, en caso de que necesite solo ciertas funciones importadas de su herramientas.js, entonces puedes usar un asignación de desestructuración que es compatible con node.js desde la versión 6.4 - ver nodo.verde.


Ejemplo: (ambos archivos están en la misma carpeta)

herramientas.js

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

principal.js

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

console.log(isEven(10));

salida: true


Esto también evita que asigne esas funciones como propiedades de otro objeto como es el caso en la siguiente asignación (común):

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

donde necesitas llamar tools.isEven(10).


NOTA:

No olvide poner el prefijo de su nombre de archivo con la ruta correcta - incluso si ambos archivos están en la misma carpeta, necesita prefijar con ./

De Documentos de Node.js:

Sin un '/', './' o '../' inicial para indicar un archivo, el módulo debe ser un módulo principal o debe cargarse desde una carpeta node_modules.

contestado el 17 de mayo de 18 a las 09:05

Incluya el archivo y ejecútelo en un contexto dado (no global)

fileToInclude.js

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

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

respondido 09 mar '15, 12:03

Esta es la mejor forma que he creado hasta ahora.

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

Aún necesita informar lo que desea exportar

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

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

Lara.prototype.webServer = null;

module.exports.Lara = Lara;

Respondido 27 Jul 13, 16:07

También estaba buscando una opción para incluir código sin escribir módulos, resp. use las mismas fuentes independientes probadas de un proyecto diferente para un servicio Node.js, y jmparatteLa respuesta lo hizo por mí.

El beneficio es que no contamina el espacio de nombres, no tengo problemas con "use strict"; y funciona bien.

Aquí un ser completados muestra:

Secuencia de comandos para cargar - /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'
    }

}

Espero que esto haya sido útil de alguna manera.

contestado el 23 de mayo de 17 a las 12:05

Como si tuvieras un archivo abc.txt ¿y muchos más?

Crea 2 archivos: fileread.js y fetchingfile.js, A continuación, en fileread.js escribe este código:

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 escribe este código:

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

Ahora, en una terminal: $ node fetchingfile.js --file = abc.txt

Estás pasando el nombre del archivo como argumento, además incluye todos los archivos en readfile.js en lugar de pasarlo.

Muchas Gracias

Respondido el 23 de Septiembre de 16 a las 17:09

Otro método cuando se usa el framework node.js y express.js

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

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

almacenar esto en un archivo js llamado sy en la carpeta statics

Ahora para usar la función

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

Respondido el 07 de diciembre de 16 a las 02:12

Puedes simplemente require('./filename').

Por ejemplo.

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

Tenga en cuenta que:

  1. no puede escuchar PORT en el archivo secundario, solo el módulo principal expreso tiene un oyente PORT
  2. El niño está usando 'Enrutador', no el módulo expreso principal.

Respondido 22 Feb 17, 10:02

Para convertir "herramientas" en un módulo, no veo nada difícil. A pesar de todas las otras respuestas, todavía recomendaría el uso de module.exports:

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

Ahora necesitamos asignar estas exportaciones al alcance global (en su aplicación | index | server.js)

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

Ahora puede referirse y llamar a la función como:

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

Respondido el 18 de junio de 19 a las 16:06

Para probar el módulo de forma interactiva ./test.js en un entorno Unix, se podría usar algo como esto:

    >> node -e "eval(''+require('fs').readFileSync('./test.js'))" -i
    ...

respondido 10 mar '21, 19:03

Uso:

var mymodule = require("./tools.js")

aplicación.js:

module.exports.<your function> = function () {
    <what should the function do>
}

respondido 22 nov., 18:02

Casi nunca debería utilizar un directorio completo. Debería considerar el uso de rutas relativas como: ./tools.js - Mateo D Auld

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.