Подтвердить что ты не робот

Могу ли я загрузить несколько файлов с одним требованием?

Возможно, этот вопрос немного глупый, но можно ли загружать несколько файлов .js с одним требованием? например:

var mylib = require('./lib/mylibfiles');

и используйте:

mylib.foo(); //return "hello from one"

mylib.bar(): //return "hello from two"

И в папке mylibfiles будет два файла:

One.js

exports.foo= function(){return "hello from one";}

Two.js

exports.bar= function(){return "hello from two";}

Я подумывал поместить package.json в папку, которая говорит, чтобы загрузить все файлы, но я не знаю, как это сделать. Другой подход, который я думал, - иметь index.js, который все экспортирует, но я буду дублировать работу.

Спасибо!!

P.D: Я работаю с nodejs v0.611 на машине Windows 7.

4b9b3361

Ответ 1

Прежде всего использование require не дублирует ничего. Он загружает модуль и кэширует его, поэтому вызов require снова получит его из памяти (таким образом, вы можете модифицировать модуль на лету без взаимодействия с его исходным кодом - это иногда желательно, например, когда вы хотите сохранить db-соединение внутри модуля).

Также package.json ничего не загружает и вообще не взаимодействует с вашим приложением. Он используется только для npm.

Теперь вы не можете требовать сразу нескольких модулей. Например, что произойдет, если обе One.js и Two.js определили функцию с тем же именем? Есть больше проблем.

Но что вы можете сделать, это написать дополнительный файл, скажем modules.js со следующим содержанием

module.exports = {
   one : require('./one.js'),
   two : require('./two.js'),
   /* some other modules you want */
}

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

var modules = require('./modules.js');
modules.one.foo();
modules.two.bar();

Ответ 2

Да, вам может потребоваться папка в качестве модуля, в соответствии с node docs. Скажем, вы хотите потребовать() папку с именем ./mypack/.

Внутри ./mypack/ создайте файл package.json с name папки и javascript файл main с тем же именем внутри каталога ./lib/.

{
  "name" : "mypack",
  "main" : "./lib/mypack.js"
}

Теперь вы можете использовать require('./mypack') и node будет загружать ./mypack/lib/mypack.js.

Однако, если вы не включили этот файл package.json, он все равно может работать. Без файла node будет пытаться загрузить ./mypack/index.js, или если это не так, ./mypack/index.node.

Я понимаю, что это может быть полезно, если вы разделили свою программу на многие файлы javascript, но не хотите их конкатенировать для развертывания.

Ответ 3

У меня есть фрагмент кода, который требует более одного модуля, но он не сжимает их вместе, как предлагает ваш пост. Однако это можно преодолеть с помощью трюка, который я нашел.

function requireMany () {
    return Array.prototype.slice.call(arguments).map(function (value) {
        try {
            return require(value)
        }
        catch (event) {
            return console.log(event)
        }
    })
}

И вы используете его как таковой

requireMany("fs", "socket.io", "path")

Что вернет

[ fs {}, socketio {}, path {} ]

Если модуль не найден, на консоль будет отправлена ​​ошибка. Это не сломает программу. Ошибка будет показана в массиве как undefined. Массив не будет короче, потому что один из модулей не смог загрузить.

Затем вы можете привязать те каждый из этих элементов массива к имени переменной, например:

var [fs, socketio, path] = requireMany("fs", "socket.io", "path")

Он по существу работает как объект, но назначает ключи и их значения глобальному пространству имен. Итак, в вашем случае вы можете сделать:

var [foo, bar] = requireMany("./foo.js", "./bar.js")
foo() //return "hello from one"
bar() //return "hello from two"

И если вы хотите, чтобы он нарушил программу при ошибке, просто используйте эту модифицированную версию, которая меньше

function requireMany () {
    return Array.prototype.slice.call(arguments).map(require)
}

Ответ 4

Я делал что-то похожее на то, что @freakish предлагает в своем ответе в проекте, где у меня есть список тестовых сценариев, которые включаются в настройку тестирования Puppeteer + Jest. Мои тестовые файлы соответствуют соглашению об именах testname1.js - testnameN.js, и я смог использовать функцию генератора, чтобы запросить N файлов из определенного каталога, используя следующий подход:

const fs = require('fs');
const path = require('path');

module.exports = class FilesInDirectory {

    constructor(directory) {

        this.fid = fs.readdirSync(path.resolve(directory));
        this.requiredFiles = (this.fid.map((fileId) => {
            let resolvedPath = path.resolve(directory, fileId);
            return require(resolvedPath);
        })).filter(file => !!file);

    }

    printRetrievedFiles() {
        console.log(this.requiredFiles);
    }

    nextFileGenerator() {

        const parent = this;
        const fidLength = parent.requiredFiles.length;

        function* iterate(index) {
            while (index < fidLength) {
                yield parent.requiredFiles[index++];
            }
        }
        return iterate(0);
    }

}

Затем используйте так:

//Use in test
const FilesInDirectory = require('./utilities/getfilesindirectory');
const StepsCollection = new FilesInDirectory('./test-steps');
const StepsGenerator = StepsCollection.nextTestGenerator();

//Assuming we're in an async function
await StepsGenerator.next().value.FUNCTION_REQUIRED_FROM_FILE(someArg);