node.js wymaga wszystkich plików w folderze?

Odpowiedzi:

515

Gdy podana jest ścieżka folderu, będzie szukał pliku index.js w tym folderze; jeśli istnieje, wykorzystuje to, a jeśli nie, to zawiedzie.

Prawdopodobnie najbardziej sensowne byłoby (jeśli masz kontrolę nad folderem) utworzenie pliku index.js, a następnie przypisanie wszystkich „modułów”, a następnie po prostu tego wymagać.

twoj_plik.js

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

index.js

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

Jeśli nie znasz nazw plików, powinieneś napisać jakiś moduł ładujący.

Przykład roboczy programu ładującego:

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

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

// Continue application logic here
tbranyen
źródło
152
Aby dodać wyjaśnienie: Gdy requirepodano ścieżkę do folderu, będzie szukał index.jsw tym folderze; jeśli istnieje, wykorzystuje to, a jeśli nie, to zawiedzie. Zobacz github.com/christkv/node-mongodb-native, aby zobaczyć przykład tego w świecie rzeczywistym: W index.jskatalogu głównym jest wymagany ./lib/mongodbkatalog; ./lib/mongodb/index.js'udostępnia wszystko inne w tym katalogu.
Trevor Burnham,
22
requirejest funkcją synchroniczną, więc nie ma korzyści z oddzwaniania. Zamiast tego użyłbym fs.readdirSync.
Rafał Sobota
4
Dzięki, napotkałem dzisiaj ten sam problem i pomyślałem „dlaczego nie ma potrzeby ('./ trasy / *')?”.
Richard Clayton,
3
@RobertMartin jest przydatny, gdy nie potrzebujesz uchwytu do niczego eksportowanego; na przykład, gdybym po prostu chciał przekazać instancję aplikacji Express do zestawu plików, które wiązałyby trasy.
Richard Clayton
2
@ TrevorBurnham Aby dodać, główny plik (tj. Plik index.js) katalogu można zmienić za pośrednictwem package.jsontego katalogu. Tak jak:{main: './lib/my-custom-main-file.js'}
antytoksyczny
187

Polecam użycie glob do wykonania tego zadania.

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

glob.sync( './routes/**/*.js' ).forEach( function( file ) {
  require( path.resolve( file ) );
});
Diogo Cardoso
źródło
12
Wszyscy powinni skorzystać z tej odpowiedzi;)
Jamie Hutber
2
Najlepsza odpowiedź! Łatwiej niż wszystkie inne opcje, szczególnie w przypadku folderów potomnych rekurencyjnych, które zawierają pliki, które musisz dołączyć.
ngDeveloper
1
Polecaj globowanie ze względu na ogólną kontrolę nad zestawami kryteriów specyfikacji plików, które możesz określić.
stephenwil,
6
glob? masz na myśli glob-savior-of-the-nodejs-race. Najlepsza odpowiedź.
deepelement
3
Użyj map () do zapisania linków: const tras = glob.sync ('./ tras / ** / *. Js'). Map (plik => wymagają (path.resolve (plik)));
lexa-b
71

Bazując na rozwiązaniu @ tbranyen, tworzę index.jsplik, który ładuje dowolne skrypty javascript w bieżącym folderze jako część 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);
  }
});

Następnie możesz requireten katalog z dowolnego innego miejsca.

Greg Wang
źródło
5
Wiem, że ma to ponad rok, ale możesz też wymagać plików JSON, więc być może coś takiego /\.js(on)?$/byłoby lepsze. Nie jest też !== nullzbędny?
59

Inną opcją jest użycie pakietu wymagany-katalog, który pozwala wykonać następujące czynności. Obsługuje również rekurencję.

var requireDir = require('require-dir');
var dir = requireDir('./path/to/dir');
studgeek
źródło
3
+1 dla, require-dirponieważ automatycznie wyklucza plik wywołujący (indeks) i domyślnie przyjmuje bieżący katalog. Doskonały.
biofractal
2
W npm jest jeszcze kilka podobnych pakietów: wymagania-wszystkie, wymagania-katalog, wymagania-katalog i inne. Najczęściej pobierane wydają się być wymagane, przynajmniej w lipcu 2015 r.
Mnebuerquo
wymagany-katalog jest teraz najczęściej pobierany (ale przede wszystkim nie obsługuje wykluczania plików w momencie pisania)
Sean Anderson
Trzy lata po powyższym komentarzu Seana require-dirdodano filteropcję.
givemesnacks
7

Mam folder / pola pełne plików z jedną klasą, na przykład:

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

Upuść to w polach / index.js, aby wyeksportować każdą klasę:

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

To sprawia, że ​​moduły zachowują się bardziej jak w Pythonie:

var text = new Fields.Text()
var checkbox = new Fields.Checkbox()
blured
źródło
6

Jeszcze jedną opcją jest połączenie wszystkich wymaganych pakietów z najpopularniejszych pakietów.

Najpopularniejszy require-dirnie ma opcji filtrowania plików / katalogów i nie ma mapfunkcji (patrz poniżej), ale używa małej sztuczki, aby znaleźć bieżącą ścieżkę modułu.

Po drugie, według popularności require-allma filtrowanie wyrażeń regularnych i przetwarzanie wstępne, ale brakuje mu ścieżki względnej, więc musisz użyć __dirname(ma to zalety i przeciwieństwa):

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

Wspomniany tutaj require-indexjest dość minimalistyczny.

Ze mapmożna zrobić wstępne przetwarzanie, jak tworzyć obiekty i przekazać wartości config (zakładając modułów poniżej konstruktorów eksportu):

// 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
źródło
5

Wiem, że to pytanie ma ponad 5 lat i podane odpowiedzi są dobre, ale chciałem czegoś nieco mocniejszego dla express, więc stworzyłem express-map2pakiet dla npm. Chciałem to nazwać po prostu express-map, ale ludzie w Yahoo już mają pakiet o tej nazwie, więc musiałem zmienić nazwę mojego pakietu.

1. podstawowe zastosowanie:

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

użycie kontrolera:

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

};

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

    foo: function(req,res){

    },

    bar: function(req,res){

    }

};

2. zaawansowane użycie z prefiksami:

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

Jak widać, oszczędza to mnóstwo czasu i sprawia, że ​​routing aplikacji jest bardzo prosty do napisania, utrzymania i zrozumienia. obsługuje wszystkie czasowniki http, które wyrażają wsparcie, a także specjalną .all()metodę.

r3wt
źródło
3

Jeden moduł, którego używałem do tego dokładnego przypadku użycia, jest wymagany .

Rekurencyjnie wymaga wszystkich plików w danym katalogu i jego podkatalogach, o ile nie pasują one do excludeDirswłaściwości.

Pozwala także określić filtr pliku i dowiedzieć się, w jaki sposób uzyskać klucze zwróconego skrótu z nazw plików.

Thorsten Lorenz
źródło
2

Korzystam z modułu kopiowania do modułów węzłów, aby utworzyć pojedynczy plik, który wymaga wszystkich plików w naszym systemie opartym na NodeJS.

Kod naszego pliku narzędziowego wygląda następująco:

/**
 * Module dependencies.
 */

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

We wszystkich plikach większość funkcji jest zapisywana jako eksport, podobnie jak:

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

Zatem, aby użyć dowolnej funkcji z pliku, wystarczy wywołać:

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

var response = utility.function2(); // or whatever the name of the function is
Scottott
źródło
2

Rozwijanie tego glob rozwiązania. Zrób to, jeśli chcesz zaimportować wszystkie moduły z katalogu do, index.jsa następnie zaimportować to index.jsw innej części aplikacji. Zauważ, że literały szablonów nie są obsługiwane przez silnik podświetlania używany przez stackoverflow, więc kod może tutaj wyglądać dziwnie.

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;

Pełny przykład

Struktura katalogów

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

Z projektu wewnętrznego z glob zainstalowanym uruchomnode example.js

$ node example.js
foo ran
bar run
keepit ran unexpected
foo ran
bar run
keepit ran unexpected
jtlindsey
źródło
1

Wymagaj wszystkich plików z routesfolderu i zastosuj jako oprogramowanie pośrednie. Nie są wymagane żadne zewnętrzne moduły.

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

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

Korzystanie z tej funkcji może wymagać całego reż.

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
źródło
-2

Jeśli dołączysz wszystkie pliki * .js do katalogu („app / lib / *. Js”):

W katalogu app / lib

przyklad.js:

module.exports = function (example) { }

przyklad-2.js:

module.exports = function (example2) { }

W aplikacji katalogowej utwórz plik index.js

index.js:

module.exports = require('./app/lib');
Faizal Pribadi
źródło