node.js memerlukan semua file dalam folder?

Jawaban:

515

Ketika mengharuskan diberikan path folder, itu akan mencari file index.js di folder itu; jika ada, ia menggunakan itu, dan jika tidak ada, itu gagal.

Mungkin akan lebih masuk akal (jika Anda memiliki kendali atas folder) untuk membuat file index.js dan kemudian menetapkan semua "modul" dan kemudian hanya memerlukannya.

yourfile.js

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

index.js

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

Jika Anda tidak tahu nama file Anda harus menulis semacam loader.

Contoh kerja loader:

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

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

// Continue application logic here
tbranyen
sumber
152
Untuk menambahkan beberapa klarifikasi: Ketika requirediberi lintasan folder, ia akan mencari index.jsdi dalam folder itu; jika ada, ia menggunakan itu, dan jika tidak ada, itu gagal. Lihat github.com/christkv/node-mongodb-native untuk contoh dunia nyata ini: Ada index.jsdi direktori root yang memerlukan ./lib/mongodb, direktori; ./lib/mongodb/index.js'membuat segala sesuatu yang lain di direktori itu tersedia.
Trevor Burnham
22
requireadalah fungsi sinkron sehingga tidak ada manfaat dari panggilan balik. Saya akan menggunakan fs.readdirSync sebagai gantinya.
Rafał Sobota
4
Terima kasih, mengalami masalah yang sama hari ini dan berpikir "mengapa tidak ada persyaratan ('./ rute / *')?".
Richard Clayton
3
@RobertMartin berguna ketika Anda tidak perlu menangani apa pun yang diekspor; misalnya, jika saya hanya ingin meneruskan contoh aplikasi Express ke satu set file yang akan mengikat rute.
Richard Clayton
2
@TrevorBurnham Untuk menambahkan, file utama (yaitu index.js) file direktori dapat diubah melalui package.jsondalam direktori ini. Seperti itu:{main: './lib/my-custom-main-file.js'}
antitoksik
187

Saya sarankan menggunakan glob untuk menyelesaikan tugas itu.

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

glob.sync( './routes/**/*.js' ).forEach( function( file ) {
  require( path.resolve( file ) );
});
Diogo Cardoso
sumber
12
Semua orang harus menggunakan jawaban ini;)
Jamie Hutber
2
Jawaban Terbaik! Lebih mudah daripada semua opsi lain, terutama untuk folder rekursif-anak yang memiliki file yang perlu Anda sertakan.
ngDeveloper
1
Rekomendasikan globbing karena kontrol keseluruhan yang Anda miliki atas set kriteria filespec yang dapat Anda tentukan.
stephenwil
6
glob? Anda maksud glob-savior-of-the-nodejs-race. Jawaban Terbaik.
deepelement
3
Gunakan map () untuk menyimpan tautan: const route = glob.sync ('./ routes / ** / *. Js'). Map (file => butuhkan (path.resolve (file)));
lexa-b
71

Berdasarkan solusi @ tbranyen, saya membuat index.jsfile yang memuat javascripts sewenang-wenang di folder saat ini sebagai bagian dari 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);
  }
});

Maka Anda dapat requiredirektori ini dari mana saja.

Greg Wang
sumber
5
Saya tahu ini lebih dari satu tahun, tetapi Anda sebenarnya dapat memerlukan file JSON juga, jadi mungkin sesuatu seperti /\.js(on)?$/akan lebih baik. Juga tidak !== nullberlebihan?
59

Pilihan lain adalah menggunakan paket dir-membutuhkan yang memungkinkan Anda melakukan hal berikut. Ini mendukung rekursi juga.

var requireDir = require('require-dir');
var dir = requireDir('./path/to/dir');
studgeek
sumber
3
+1 untuk require-dirkarena secara otomatis mengecualikan file panggilan (indeks) dan default ke direktori saat ini. Sempurna.
biofractal
2
Di npm ada beberapa paket serupa: memerlukan-semua, direktori-butuhkan, direktori-dir, dan lain-lain. Yang paling banyak diunduh tampaknya memerlukan semua, setidaknya pada bulan Juli 2015.
Mnebuerquo
Wajib-dir sekarang menjadi yang paling banyak diunduh (tetapi terutama tidak mendukung pengecualian file pada saat penulisan)
Sean Anderson
Tiga tahun setelah komentar Sean di atas, require-dirmenambahkan filteropsi.
givemesnacks
7

Saya memiliki folder / bidang yang penuh dengan file dengan masing-masing kelas, mis:

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

Letakkan ini di bidang / index.js untuk mengekspor setiap kelas:

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

Ini membuat modul bertindak lebih seperti pada Python:

var text = new Fields.Text()
var checkbox = new Fields.Checkbox()
berbaur
sumber
6

Satu lagi opsi adalah keharusan-dir-semua menggabungkan fitur dari paket paling populer.

Paling populer require-dirtidak memiliki opsi untuk memfilter file / dir dan tidak memiliki mapfungsi (lihat di bawah), tetapi menggunakan trik kecil untuk menemukan jalur modul saat ini.

Kedua berdasarkan popularitas require-allmemiliki penyaringan dan preprocessing regexp, tetapi tidak memiliki jalur relatif, sehingga Anda perlu menggunakan __dirname(ini memiliki pro dan kontra) seperti:

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

Disebutkan di sini require-indexcukup minimalis.

Dengan mapAnda dapat melakukan beberapa preprocessing, seperti membuat objek dan memberikan nilai konfigurasi (dengan asumsi modul di bawah ekspor konstruktor):

// 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
sumber
5

Saya tahu pertanyaan ini berumur 5+ tahun, dan jawaban yang diberikan bagus, tetapi saya ingin sesuatu yang lebih kuat untuk diekspresikan, jadi saya membuat express-map2paket untuk npm. Saya akan menyebutkannya secara sederhana express-map, namun orang - orang di yahoo sudah memiliki paket dengan nama itu, jadi saya harus mengganti nama paket saya.

1. penggunaan dasar:

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

penggunaan pengontrol:

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

};

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

    foo: function(req,res){

    },

    bar: function(req,res){

    }

};

2. penggunaan lanjutan, dengan awalan:

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

Seperti yang Anda lihat, ini menghemat banyak waktu dan membuat perutean aplikasi Anda menjadi mudah untuk ditulis, dirawat, dan dipahami. ini mendukung semua kata kerja http yang mengekspresikan dukungan, serta .all()metode khusus .

r3wt
sumber
3

Satu modul yang telah saya gunakan untuk kasus penggunaan yang tepat ini adalah wajib semua .

Secara rekursif membutuhkan semua file dalam direktori dan sub direktori yang diberikan selama mereka tidak cocok dengan excludeDirsproperti.

Ini juga memungkinkan menentukan filter file dan cara menurunkan kunci hash yang dikembalikan dari nama file.

Thorsten Lorenz
sumber
2

Saya menggunakan modul simpul, salin ke modul untuk membuat satu file yang memerlukan semua file di sistem berbasis NodeJS kami.

Kode untuk file utilitas kami terlihat seperti ini:

/**
 * Module dependencies.
 */

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

Di semua file, sebagian besar fungsi ditulis sebagai ekspor, seperti:

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

Jadi, untuk menggunakan fungsi apa pun dari file, Anda cukup memanggil:

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

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

Memperluas solusi ini glob . Lakukan ini jika Anda ingin mengimpor semua modul dari direktori ke index.jsdan kemudian mengimpornya index.jsdi bagian lain dari aplikasi. Perhatikan bahwa templat literal tidak didukung oleh mesin penyorotan yang digunakan oleh stackoverflow sehingga kode mungkin terlihat aneh di sini.

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;

Contoh Lengkap

Struktur direktori

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 / tak terduga.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';

Dari proyek dalam dengan glob terinstal , jalankannode example.js

$ node example.js
foo ran
bar run
keepit ran unexpected
foo ran
bar run
keepit ran unexpected
jindlindsey
sumber
1

Wajibkan semua file dari routesfolder dan terapkan sebagai middleware. Tidak diperlukan modul eksternal.

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

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

Dengan menggunakan fungsi ini, Anda dapat meminta dir lengkap.

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);
M. Hamza Rajput
sumber
-2

Jika Anda memasukkan semua file * .js dalam contoh direktori ("app / lib / *. Js"):

Dalam aplikasi direktori / lib

contoh.js:

module.exports = function (example) { }

contoh-2.js:

module.exports = function (example2) { }

Dalam aplikasi direktori buat index.js

index.js:

module.exports = require('./app/lib');
Faizal Pribadi
sumber