node.js bir klasördeki tüm dosyaları gerektiriyor mu?


330

Node.js dosyasındaki bir klasördeki tüm dosyaları nasıl talep edebilirim?

gibi bir şeye ihtiyacım var:

files.forEach(function (v,k){
  // require routes
  require('./routes/'+v);
}};

4
var routes = require('auto-load')('routes');yeni auto-loadmodülle [Ben onu yaratmaya yardım ettim].
Francisco Presencia

Yanıtlar:


515

Gereksinim bir klasörün yolu verildiğinde, o klasörde bir index.js dosyasını arar; eğer varsa, bunu kullanır ve yoksa başarısız olur.

Bir index.js dosyası oluşturmak ve daha sonra tüm "modülleri" atamak büyük olasılıkla (klasör üzerinde denetiminiz varsa) ve bu sadece bunu gerektirir.

yourfile.js

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

index.js

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

Dosya adlarını bilmiyorsanız bir çeşit yükleyici yazmalısınız.

Bir yükleyicinin çalışma örneği:

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

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

// Continue application logic here

152
Biraz açıklama eklemek için: Bir requireklasörün yolu verildiğinde, o klasörde bir dosya arar index.js; eğer varsa, bunu kullanır ve yoksa başarısız olur. Bunun gerçek dünya örneği için github.com/christkv/node-mongodb-native adresine bakın : index.jsKök dizinde gereken ./lib/mongodbbir dizin var; ./lib/mongodb/index.js'dizindeki diğer her şeyi kullanılabilir hale getirir.
Trevor Burnham

22
requiresenkronize bir fonksiyondur, bu nedenle geri aramadan fayda sağlanmaz. Bunun yerine fs.readdirSync kullanırdım.
Rafał Sobota

4
Teşekkürler, bugün aynı sorunla karşılaştı ve "neden bir gereklilik yok ('./ route / *')?" Diye düşündü.
Richard Clayton

3
@RobertMartin dışa aktarılan herhangi bir şey için bir tutamağa ihtiyacınız olmadığında kullanışlıdır; Örneğin, bir Express uygulaması örneğini rotaları bağlayacak bir dosya kümesine geçirmek istersem.
Richard Clayton

2
@TrevorBurnham Eklemek için, bir dizinin ana dosyası (yani index.js) dosyası package.jsonbu dizinde değiştirilebilir . Bunun gibi:{main: './lib/my-custom-main-file.js'}
antitoksik

187

Bu görevi yerine getirmek için glob kullanmanızı tavsiye ederim .

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

glob.sync( './routes/**/*.js' ).forEach( function( file ) {
  require( path.resolve( file ) );
});

12
Herkes bu cevabı kullanmalı;)
Jamie Hutber

2
En iyi cevap! Diğer seçeneklerden daha kolay, özellikle eklemeniz gereken dosyaları olan özyinelemeli alt klasörler için.
ngDeveloper

1
Belirtebileceğiniz dosyabelirtimi kümeleri üzerinde sahip olduğunuz genel kontrol nedeniyle globbing'i önerin.
stephenwil

6
glob? demek istedin glob-savior-of-the-nodejs-race. En iyi cevap.
deepelement

3
Bağlantıları kaydetmek için map () kullanın: const route = glob.sync ('./ route / ** / *. Js'). Map (dosya => gerektirir (path.resolve (dosya)));
lexa-b

71

@ Tbranyen çözüm temel, bir index.jsparçası olarak geçerli klasör altında keyfi javascripts yükleyen bir dosya oluşturun 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);
  }
});

Sonra requirebu dizini başka herhangi bir yerden yapabilirsiniz .


5
Bunun bir yıldan daha eski olduğunu biliyorum, ama aslında JSON dosyalarına da ihtiyacınız olabilir, bu yüzden belki /\.js(on)?$/de daha iyi bir şey olabilir. Ayrıca !== nullgereksiz değil mi?

59

Başka bir seçenek, aşağıdakileri yapmanıza izin veren requir-dir paketini kullanmaktır . Özyinelemeyi de destekler.

var requireDir = require('require-dir');
var dir = requireDir('./path/to/dir');

3
+1 require-dir, çağıran dosyayı (dizin) otomatik olarak hariç tuttuğundan ve varsayılan olarak geçerli dizine geçer. Mükemmel.
biofractal

2
Npm'de birkaç benzer paket daha vardır: requir-all, requir-directory, requir-dir ve diğerleri. En çok indirilen, en azından Temmuz 2015'te her şeye ihtiyaç duyuyor gibi görünüyor.
Mnebuerquo

requir-dir şimdi en çok indirilen (ancak özellikle yazma sırasında dosya hariç tutmayı desteklemiyor)
Sean Anderson

Sean'ın yukarıdaki yorumundan üç yıl sonra require-dirbir filterseçenek ekledi .
givemesnacks

7

Bir klasör / alanları her biri, tek bir sınıf ile dolu dosyaları var:

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

Her sınıfı dışa aktarmak için bunu fields / index.js alanına bırakın:

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

Bu, modüllerin Python'daki gibi hareket etmesini sağlar:

var text = new Fields.Text()
var checkbox = new Fields.Checkbox()

6

Bir seçenek daha zorunlu-dir-all , en popüler paketlerin birleştiren özelliklerdir.

En popüler require-dirdosyaları / dizinleri filtreleme seçeneklerine sahip değildir vemap işlevi yoktur (aşağıya bakın), ancak modülün geçerli yolunu bulmak için küçük numaralar kullanır.

İkinci olarak popülerliğe require-allgöre regexp filtreleme ve önişleme vardır, ancak göreceli yoldan yoksundur, bu yüzden aşağıdaki gibi kullanmanız gerekir __dirname(bunun artıları ve kontrasları vardır):

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

Burada bahsettiğim require-indexşey oldukça minimalist.

Bununla birlikte map, nesne oluşturma ve yapılandırma değerlerini geçirme (dışa aktarma kurucularının altındaki modüller varsayarak) gibi bazı ön işlemler yapabilirsiniz:

// 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`.

5

Bu sorunun 5+ yaşında olduğunu biliyorum ve verilen cevaplar iyi, ama ekspres için biraz daha güçlü bir şey istedim, bu yüzden express-map2npm için paket oluşturdum . Basitçe adlandıracaktım express-map, ancak yahoo'daki insanların zaten bu adla bir paketi var, bu yüzden paketimi yeniden adlandırmak zorunda kaldım.

1. temel kullanım:

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

denetleyici kullanımı:

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

};

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

    foo: function(req,res){

    },

    bar: function(req,res){

    }

};

2. önekler ile gelişmiş kullanım:

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

Gördüğünüz gibi, bu tonlarca zaman kazandırır ve uygulamanızın yönlendirmesini yazmak, sürdürmek ve anlamak için ölü hale getirir. özel .all()yöntemi yanı sıra destek ifade tüm http fiilleri destekler .


3

Bu tam kullanım durumu için kullandığım bir modül, hepsi gerektirir .

excludeDirsÖzelliğiyle eşleşmedikleri sürece belirli bir dizindeki ve alt dizinlerindeki tüm dosyaları yinelemeli olarak gerektirir .

Ayrıca bir dosya filtresi ve döndürülen karma anahtarlarının dosya adlarından nasıl türetileceğini belirtir.


2

NodeJS tabanlı sistemimizdeki tüm dosyaları gerektirecek tek bir dosya oluşturmak için node modülleri kopyala modülünü kullanıyorum .

Yardımcı programımızın kodu şuna benzer:

/**
 * Module dependencies.
 */

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

Tüm dosyalarda, işlevlerin çoğu dışa aktarma olarak yazılır, şöyle:

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

Yani, bir dosyadan herhangi bir işlevi kullanmak için, sadece şunu çağırırsınız:

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

var response = utility.function2(); // or whatever the name of the function is

2

Bu glob çözüm üzerinde genişleyen . Tüm modülleri bir dizinden index.jsiçe aktarmak ve ardından bunu index.jsuygulamanın başka bir bölümüne almak istiyorsanız bunu yapın . Şablon değişmezlerinin stackoverflow tarafından kullanılan vurgulama motoru tarafından desteklenmediğini ve kodun burada garip görünebileceğini unutmayın.

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;

Tam Örnek

Dizin yapısı

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 Yüklü proje içinden , çalıştırnode example.js

$ node example.js
foo ran
bar run
keepit ran unexpected
foo ran
bar run
keepit ran unexpected


1

routesKlasördeki tüm dosyaları zorunlu kılın ve ara katman yazılımı olarak uygulayın. Harici modül gerekmez.

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

// apply as middleware
readdirSync("./routes").map((r) => app.use("/api", require("./routes/" + r)));

0

Bu işlevi kullanarak tam bir dizin gerekebilir.

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 dosyalarının tümünü dizin örneğine eklerseniz ("app / lib / *. Js"):

Dizin uygulamasında / lib

example.js:

module.exports = function (example) { }

Örnek-2.js:

module.exports = function (example2) { }

Dizin uygulamasında index.js oluşturun

index.js:

module.exports = require('./app/lib');
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.