Могу ли я загрузить несколько файлов с одним требованием?
Возможно, этот вопрос немного глупый, но можно ли загружать несколько файлов .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.
Ответы
Ответ 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);