node.js требует все файлы в папке?

330

Как мне требовать все файлы в папке в node.js?

нужно что-то вроде:

files.forEach(function (v,k){
  // require routes
  require('./routes/'+v);
}};
Гарри
источник
4
var routes = require('auto-load')('routes');с новым auto-loadмодулем [я помог создать его].
Франциско Презенсия
1
Документация: nodejs.org/api/modules.html#modules_folders_as_modules
Xeoncross

Ответы:

516

Когда require указан путь к папке, он будет искать файл index.js в этой папке; если он есть, он использует его, а если его нет, он терпит неудачу.

Вероятно, было бы наиболее разумно (если у вас есть контроль над папкой) создать файл index.js, а затем назначить все «модули», а затем просто потребовать этого.

yourfile.js

var routes = require("./routes");

index.js

exports.something = require("./routes/something.js");
exports.others = require("./routes/others.js");

Если вы не знаете имен файлов, вам следует написать какой-нибудь загрузчик.

Рабочий пример загрузчика:

var normalizedPath = require("path").join(__dirname, "routes");

require("fs").readdirSync(normalizedPath).forEach(function(file) {
  require("./routes/" + file);
});

// Continue application logic here
tbranyen
источник
152
Чтобы добавить некоторые пояснения: когда requireуказан путь к папке, он будет искать index.jsв этой папке; если он есть, он использует его, а если его нет, он терпит неудачу. См. Github.com/christkv/node-mongodb-native для реального примера этого: есть index.jsв корневом каталоге, который требует ./lib/mongodb, каталог; ./lib/mongodb/index.js'делает все остальное в этом каталоге доступным.
Тревор Бернхам
22
requireявляется синхронной функцией, поэтому нет никаких преимуществ от обратного вызова. Я бы использовал fs.readdirSync вместо этого.
Рафал Собота
4
Спасибо, столкнулся с этой же проблемой сегодня и подумал: «Почему нет необходимости ('./ways / *')?".
Ричард Клейтон
3
@RobertMartin это полезно, когда вам не нужен дескриптор экспортируемой информации; например, если я просто хочу передать экземпляр приложения Express в набор файлов, которые будут связывать маршруты.
Ричард Клэйтон
2
@TrevorBurnham Чтобы добавить, основной файл (то есть index.js) файла каталога может быть изменен через package.jsonв этом каталоге. Вроде так:{main: './lib/my-custom-main-file.js'}
антитоксический
187

Я рекомендую использовать glob для выполнения этой задачи.

var glob = require( 'glob' )
  , path = require( 'path' );

glob.sync( './routes/**/*.js' ).forEach( function( file ) {
  require( path.resolve( file ) );
});
Диого Кардосо
источник
12
Каждый должен использовать этот ответ;)
Джейми Хатбер
2
Лучший ответ! Проще, чем все остальные опции, особенно для дочерних рекурсивных папок, в которых есть файлы, которые нужно включить.
ngDeveloper
1
Рекомендовать глобализацию из-за общего контроля над наборами критериев filepec, которые вы можете указать.
Стивенвил
6
glob? вы имеете в виду glob-savior-of-the-nodejs-race. Лучший ответ.
углубление
3
Используйте map () для сохранения ссылок: const route = glob.sync ('./ маршруты / ** / *. Js'). Map (file => require (path.resolve (file)));
Лекса-б
71

Основываясь на решении @ tbranyen, я создаю index.jsфайл, который загружает произвольные javascript- коды в текущую папку как часть exports.

// Load `*.js` under current directory as properties
//  i.e., `User.js` will become `exports['User']` or `exports.User`
require('fs').readdirSync(__dirname + '/').forEach(function(file) {
  if (file.match(/\.js$/) !== null && file !== 'index.js') {
    var name = file.replace('.js', '');
    exports[name] = require('./' + file);
  }
});

Тогда вы можете requireэтот каталог из любого другого места.

Грег Ван
источник
5
Я знаю, что этому больше года, но на самом деле вам также могут потребоваться файлы JSON, так что, возможно, что-то вроде /\.js(on)?$/этого будет лучше. Также не является !== nullлишним?
59

Другой вариант - использовать пакет require-dir, который позволит вам сделать следующее. Он также поддерживает рекурсию.

var requireDir = require('require-dir');
var dir = requireDir('./path/to/dir');
studgeek
источник
3
+1 за, require-dirпотому что он автоматически исключает вызывающий файл (индекс) и по умолчанию использует текущий каталог. Отлично.
биофрактал
2
В npm есть еще несколько похожих пакетов: require-all, require-directory, require-dir и другие. Похоже, что самое загружаемое требуется всем, по крайней мере, в июле 2015 года.
Mnebuerquo
require-dir теперь самый загружаемый (но особенно он не поддерживает исключение файлов во время написания)
Шон Андерсон
Через три года после комментария Шона, require-dirдобавлен filterвариант.
Givemesnacks
7

У меня есть папка / поля, полные файлов с одним классом каждый, например:

fields/Text.js -> Test class
fields/Checkbox.js -> Checkbox class

Перетащите это в fields / index.js для экспорта каждого класса:

var collectExports, fs, path,
  __hasProp = {}.hasOwnProperty;

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

collectExports = function(file) {
  var func, include, _results;

  if (path.extname(file) === '.js' && file !== 'index.js') {
    include = require('./' + file);
    _results = [];
    for (func in include) {
      if (!__hasProp.call(include, func)) continue;
      _results.push(exports[func] = include[func]);
    }
    return _results;
  }
};

fs.readdirSync('./fields/').forEach(collectExports);

Это делает модули более похожими на Python:

var text = new Fields.Text()
var checkbox = new Fields.Checkbox()
blented
источник
6

Еще одна опция - require-dir-all, объединяющая функции большинства популярных пакетов.

Самый популярный require-dirне имеет опций для фильтрации файлов / каталогов и не имеет mapфункции (см. Ниже), но использует небольшую хитрость, чтобы найти текущий путь модуля.

Второе место по популярности require-allимеет фильтрация и предварительная обработка регулярных выражений, но не имеет относительного пути, поэтому вам нужно использовать __dirname(это имеет плюсы и минусы), например:

var libs = require('require-all')(__dirname + '/lib');

Упомянутое здесь require-indexдовольно минималистично.

С mapвы можете сделать некоторые предварительной обработку, как создавать объекты и передавать значение конфигурации (предполагая модули ниже экспорт конструкторов):

// Store config for each module in config object properties 
// with property names corresponding to module names 
var config = {
  module1: { value: 'config1' },
  module2: { value: 'config2' }
};

// Require all files in modules subdirectory 
var modules = require('require-dir-all')(
  'modules', // Directory to require 
  { // Options 
    // function to be post-processed over exported object for each require'd module 
    map: function(reqModule) {
      // create new object with corresponding config passed to constructor 
      reqModule.exports = new reqModule.exports( config[reqModule.name] );
    }
  }
);

// Now `modules` object holds not exported constructors, 
// but objects constructed using values provided in `config`.
alykoshin
источник
5

Я знаю, что этому вопросу более 5 лет, и приведенные ответы хороши, но я хотел что-то более мощное для экспресса, поэтому я создал express-map2пакет для npm. Я собирался назвать это просто express-map, однако у людей в Yahoo уже есть пакет с таким именем, поэтому мне пришлось переименовать мой пакет.

1. основное использование:

app.js (or whatever you call it)

var app = require('express'); // 1. include express

app.set('controllers',__dirname+'/controllers/');// 2. set path to your controllers.

require('express-map2')(app); // 3. patch map() into express

app.map({
    'GET /':'test',
    'GET /foo':'middleware.foo,test',
    'GET /bar':'middleware.bar,test'// seperate your handlers with a comma. 
});

использование контроллера:

//single function
module.exports = function(req,res){

};

//export an object with multiple functions.
module.exports = {

    foo: function(req,res){

    },

    bar: function(req,res){

    }

};

2. расширенное использование с префиксами:

app.map('/api/v1/books',{
    'GET /': 'books.list', // GET /api/v1/books
    'GET /:id': 'books.loadOne', // GET /api/v1/books/5
    'DELETE /:id': 'books.delete', // DELETE /api/v1/books/5
    'PUT /:id': 'books.update', // PUT /api/v1/books/5
    'POST /': 'books.create' // POST /api/v1/books
});

Как видите, это экономит массу времени и упрощает написание, поддержку и понимание маршрутизации вашего приложения. он поддерживает все глаголы http, которые выражают поддержку, а также специальный .all()метод.

r3wt
источник
3

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

Он рекурсивно требует все файлы в данном каталоге и его подкаталогах, если они не соответствуют excludeDirsсвойству.

Это также позволяет указать файловый фильтр и узнать, как получить ключи возвращенного хэша из имен файлов.

Торстен Лоренц
источник
2

Я использую модуль copy-to module модуля для создания единого файла, чтобы требовать все файлы в нашей системе на основе NodeJS.

Код для нашего служебного файла выглядит следующим образом:

/**
 * Module dependencies.
 */

var copy = require('copy-to');
copy(require('./module1'))
.and(require('./module2'))
.and(require('./module3'))
.to(module.exports);

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

exports.function1 = function () { // function contents };
exports.function2 = function () { // function contents };
exports.function3 = function () { // function contents };

Итак, чтобы использовать любую функцию из файла, вы просто вызываете:

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

var response = utility.function2(); // or whatever the name of the function is
scottnath
источник
2

Расширяя это glob решение. Сделайте это, если вы хотите импортировать все модули из каталога в, index.jsа затем импортировать его index.jsв другую часть приложения. Обратите внимание, что литералы шаблона не поддерживаются механизмом подсвечивания, используемым stackoverflow, поэтому код здесь может выглядеть странно.

const glob = require("glob");

let allOfThem = {};
glob.sync(`${__dirname}/*.js`).forEach((file) => {
  /* see note about this in example below */
  allOfThem = { ...allOfThem, ...require(file) };
});
module.exports = allOfThem;

Полный пример

Структура каталогов

globExample/example.js
globExample/foobars/index.js
globExample/foobars/unexpected.js
globExample/foobars/barit.js
globExample/foobars/fooit.js

globExample / example.js

const { foo, bar, keepit } = require('./foobars/index');
const longStyle = require('./foobars/index');

console.log(foo()); // foo ran
console.log(bar()); // bar ran
console.log(keepit()); // keepit ran unexpected

console.log(longStyle.foo()); // foo ran
console.log(longStyle.bar()); // bar ran
console.log(longStyle.keepit()); // keepit ran unexpected

globExample / foobars / index.js

const glob = require("glob");
/*
Note the following style also works with multiple exports per file (barit.js example)
but will overwrite if you have 2 exports with the same
name (unexpected.js and barit.js have a keepit function) in the files being imported. As a result, this method is best used when
your exporting one module per file and use the filename to easily identify what is in it.

Also Note: This ignores itself (index.js) by default to prevent infinite loop.
*/

let allOfThem = {};
glob.sync(`${__dirname}/*.js`).forEach((file) => {
  allOfThem = { ...allOfThem, ...require(file) };
});

module.exports = allOfThem;

globExample / foobars / unexpected.js

exports.keepit = () => 'keepit ran unexpected';

globExample / foobars / barit.js

exports.bar = () => 'bar run';

exports.keepit = () => 'keepit ran';

globExample / foobars / fooit.js

exports.foo = () => 'foo ran';

Изнутри проекта с glob установленным , запуститьnode example.js

$ node example.js
foo ran
bar run
keepit ran unexpected
foo ran
bar run
keepit ran unexpected
jtlindsey
источник
1

Можно использовать: https://www.npmjs.com/package/require-file-directory

  • Требовать выбранные файлы только с именем или все файлы.
  • Нет необходимости в абсолютном пути.
  • Легко понять и использовать.
Mayank Soni
источник
2
Добро пожаловать в ТАК. Пожалуйста, прочитайте эту инструкцию для обеспечения качественного ответа.
thewaywewere
1

Требовать все файлы из routesпапки и применять в качестве промежуточного программного обеспечения. Внешние модули не нужны.

// require
const path = require("path");
const { readdirSync } = require("fs");

// apply as middleware
readdirSync("./routes").map((r) => app.use("/api", require("./routes/" + r)));
Райан Dhungel
источник
0

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

const GetAllModules = ( dirname ) => {
    if ( dirname ) {
        let dirItems = require( "fs" ).readdirSync( dirname );
        return dirItems.reduce( ( acc, value, index ) => {
            if ( PATH.extname( value ) == ".js" && value.toLowerCase() != "index.js" ) {
                let moduleName = value.replace( /.js/g, '' );
                acc[ moduleName ] = require( `${dirname}/${moduleName}` );
            }
            return acc;
        }, {} );
    }
}

// calling this function.

let dirModules = GetAllModules(__dirname);
М. Хамза Раджпут
источник
-2

Если вы включили все файлы * .js в пример каталога ("app / lib / *. Js"):

В каталоге app / lib

example.js:

module.exports = function (example) { }

ПРИМЕР 2.js:

module.exports = function (example2) { }

В каталоге приложения создайте index.js

index.js:

module.exports = require('./app/lib');
Файзал Прибади
источник