В Node.js, как мне «включить» функции из других моих файлов? - PullRequest
839 голосов
/ 27 апреля 2011

Допустим, у меня есть файл с именем app.js.Довольно просто:

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

Что если у меня есть функции внутри "tools.js".Как мне импортировать их для использования в apps.js?

Или ... я должен превратить "инструменты" в модуль, а затем требовать его?<< кажется сложным, я скорее делаю основной импорт файла tools.js. </p>

Ответы [ 25 ]

1259 голосов
/ 27 апреля 2011

Вы можете запросить любой файл js, вам просто нужно объявить то, что вы хотите выставить.

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

var zemba = function () {
}

А в вашем файле приложения:

// app.js
// ======
var tools = require('./tools');
console.log(typeof tools.foo); // => 'function'
console.log(typeof tools.bar); // => 'function'
console.log(typeof tools.zemba); // => undefined
283 голосов
/ 28 апреля 2011

Если, несмотря на все остальные ответы, вы все еще хотите традиционно включить файл в исходный файл node.js, вы можете использовать это:

var fs = require('fs');

// file is included here:
eval(fs.readFileSync('tools.js')+'');
  • Конкатенация пустой строки +'' необходима для получения содержимого файла в виде строки, а не объекта (вы также можете использовать .toString(), если хотите).
  • eval () не может использоваться внутри функции, и должен вызываться внутри глобальной области видимости, иначе никакие функции или переменные не будут доступны (т.е. вы не можете создать служебную функцию include() или что-то в этом роде.

Обратите внимание, что в большинстве случаев это плохая практика , и вместо этого вам следует написать модуль . Однако в редких случаях загрязнение вашего локального контекста / пространства имен - это то, что вам действительно нужно.

Обновление 2015-08-06

Также обратите внимание, что это не будет работать с "use strict"; (когда вы находитесь в в "строгом режиме" ), потому что функции и переменные определены в "импортированном" файле недоступен по коду, который выполняет импорт. Строгий режим обеспечивает соблюдение некоторых правил, определенных новыми версиями языкового стандарта. Это может быть еще одной причиной, по которой следует избегать решения, описанного здесь.

166 голосов
/ 21 января 2015

Вам не нужны ни новые функции, ни новые модули.Вам просто нужно запустить вызываемый модуль, если вы не хотите использовать пространство имен.

в tools.js

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

в app.js

или в любом другом .js, например myController.js:

вместо

var tools = require('tools.js'), что вынуждает нас использовать пространство имен и вызывать такие инструменты, как tools.sum(1,2);

мы можем просто позвонить

require('tools.js')();

, а затем

sum(1,2);

в моем случае у меня есть файл с контроллерами ctrls.js

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

и я могу использовать Categories в любом контексте как публичный класс после require('ctrls.js')()

93 голосов
/ 11 апреля 2017

Создание двух файлов js

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

Основной файл js

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

Вывод

value: 30
39 голосов
/ 23 октября 2014

Вот простое и простое объяснение:

Содержимое 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);

Содержимое 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 () 
{
};
32 голосов
/ 09 декабря 2013

Я также искал функцию включения в NodeJS и проверил решение, предложенное Udo G - см. Сообщение https://stackoverflow.com/a/8744519/2979590. Его код не работает с моими включенными JS-файлами.Наконец я решил проблему следующим образом:

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

Конечно, это помогает.

25 голосов
/ 22 августа 2015

говорят, что мы хотим вызвать функцию ping () и add (30,20) , которая находится в lib.js файле из 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
    }
24 голосов
/ 27 июня 2012

Модуль vm в Node.js предоставляет возможность выполнять код JavaScript в текущем контексте (включая глобальный объект).См. http://nodejs.org/docs/latest/api/vm.html#vm_vm_runinthiscontext_code_filename

Обратите внимание, что на сегодняшний день в модуле vm есть ошибка, препятствующая правильному выполнению runInThisContext при вызове из нового контекста.Это имеет значение только в том случае, если ваша основная программа выполняет код в новом контексте, а затем этот код вызывает runInThisContext.См. https://github.com/joyent/node/issues/898

К сожалению, предложенный Фернандо подход with (global) не работает для именованных функций, таких как "function foo () {}"

Короче, вот включение () функция, которая работает для меня:

function include(path) {
    var code = fs.readFileSync(path, 'utf-8');
    vm.runInThisContext(code, path);
}
13 голосов
/ 05 января 2012

Удо Г. сказал:

  • eval () не может использоваться внутри функции и должен вызываться внутри глобальная область, в противном случае никакие функции или переменные доступны (то есть вы не можете создать служебную функцию include () или как то так).

Он прав, но есть способ повлиять на глобальную область видимости из функции. Улучшение своего примера:

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

include('somefile_with_some_declarations.js');

// the declarations are now accessible here.

Надеюсь, это поможет.

11 голосов
/ 27 января 2017

Другой способ сделать это, по моему мнению, это выполнить все в файле lib, когда вы вызываете функцию require () , используя (функция (/ * вещи здесь * /) {}) (); выполнение этого сделает все эти функции глобальной областью, точно так же как eval () решение

ЦСИ / 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');
            }
    }
})();

И тогда в вашем основном коде вы можете вызывать ваши функции по имени, например:

main.js

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

сделает этот вывод

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

Обратите внимание на undefined , когда вы вызываете мой object.funcFour () , он будет таким же, если вы загрузите с помощью eval () . Надеюсь, это поможет:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...