Comment dois-je exiger tous les fichiers d'un dossier dans node.js?
besoin de quelque chose comme:
files.forEach(function (v,k){
// require routes
require('./routes/'+v);
}};
Comment dois-je exiger tous les fichiers d'un dossier dans node.js?
besoin de quelque chose comme:
files.forEach(function (v,k){
// require routes
require('./routes/'+v);
}};
Réponses:
Lorsque require reçoit le chemin d'un dossier, il recherche un fichier index.js dans ce dossier; s'il y en a un, il l'utilise, et s'il n'y en a pas, il échoue.
Il serait probablement plus judicieux (si vous avez le contrôle sur le dossier) de créer un fichier index.js, puis d'affecter tous les "modules" et de simplement l'exiger.
yourfile.js
var routes = require("./routes");
index.js
exports.something = require("./routes/something.js");
exports.others = require("./routes/others.js");
Si vous ne connaissez pas les noms de fichiers, vous devez écrire une sorte de chargeur.
Exemple de travail d'un chargeur:
var normalizedPath = require("path").join(__dirname, "routes");
require("fs").readdirSync(normalizedPath).forEach(function(file) {
require("./routes/" + file);
});
// Continue application logic here
require
est donné le chemin d'un dossier, il recherchera un index.js
dans ce dossier; s'il y en a un, il l'utilise, et s'il n'y en a pas, il échoue. Voir github.com/christkv/node-mongodb-native pour un exemple concret de ceci: Il y a index.js
dans le répertoire racine qui nécessite ./lib/mongodb
, un répertoire; ./lib/mongodb/index.js'
rend tout le reste de ce répertoire disponible.
require
est une fonction synchrone, il n'y a donc aucun avantage à être rappelé. J'utiliserais plutôt fs.readdirSync.
package.json
dans ce répertoire. Comme ça:{main: './lib/my-custom-main-file.js'}
Je recommande d'utiliser glob pour accomplir cette tâche.
var glob = require( 'glob' )
, path = require( 'path' );
glob.sync( './routes/**/*.js' ).forEach( function( file ) {
require( path.resolve( file ) );
});
glob
? tu veux dire glob-savior-of-the-nodejs-race
. Meilleure réponse.
Sur la base de la solution de @ tbranyen, je crée un index.js
fichier qui charge des javascripts arbitraires dans le dossier actuel dans le cadre du 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);
}
});
Ensuite, vous pouvez require
ce répertoire à partir de n'importe où ailleurs.
Une autre option consiste à utiliser le package require-dir qui vous permet d'effectuer les opérations suivantes. Il prend également en charge la récursivité.
var requireDir = require('require-dir');
var dir = requireDir('./path/to/dir');
require-dir
car il exclut automatiquement le fichier appelant (index) et revient par défaut au répertoire courant. Parfait.
require-dir
ajouté une filter
option.
J'ai un dossier / champs plein de fichiers avec une seule classe chacun, ex:
fields/Text.js -> Test class
fields/Checkbox.js -> Checkbox class
Déposez ceci dans fields / index.js pour exporter chaque classe:
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);
Cela fait que les modules agissent plus comme ils le feraient en Python:
var text = new Fields.Text()
var checkbox = new Fields.Checkbox()
Une autre option consiste à exiger-dir-all combinant les fonctionnalités des packages les plus populaires.
Le plus populaire require-dir
n'a pas d'options pour filtrer les fichiers / répertoires et n'a pas de map
fonction (voir ci-dessous), mais utilise une petite astuce pour trouver le chemin actuel du module.
Le second par la popularité require-all
est le filtrage et le prétraitement des expressions rationnelles, mais il manque un chemin relatif, vous devez donc utiliser __dirname
(cela a des avantages et des contras) comme:
var libs = require('require-all')(__dirname + '/lib');
Mentionné ici require-index
est assez minimaliste.
Avec map
vous, vous pouvez effectuer un prétraitement, comme créer des objets et transmettre des valeurs de configuration (en supposant que les modules sous les constructeurs exportent):
// 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`.
Je sais que cette question a plus de 5 ans, et les réponses données sont bonnes, mais je voulais quelque chose d'un peu plus puissant pour express, alors j'ai créé le express-map2
package pour npm. J'allais simplement le nommer express-map
, mais les gens de Yahoo ont déjà un paquet avec ce nom, j'ai donc dû renommer mon paquet.
1. utilisation de base:
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.
});
utilisation du contrôleur:
//single function
module.exports = function(req,res){
};
//export an object with multiple functions.
module.exports = {
foo: function(req,res){
},
bar: function(req,res){
}
};
2. utilisation avancée, avec préfixes:
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
});
Comme vous pouvez le voir, cela permet d'économiser une tonne de temps et de simplifier l'écriture, la maintenance et la compréhension du routage de votre application. il prend en charge tous les verbes http qui expriment les supports, ainsi que la .all()
méthode spéciale .
Un module que j'ai utilisé pour ce cas d'utilisation exact est require-all .
Il nécessite récursivement tous les fichiers dans un répertoire donné et ses sous-répertoires tant qu'ils ne correspondent pas à la excludeDirs
propriété.
Il permet également de spécifier un filtre de fichiers et comment dériver les clés du hachage retourné à partir des noms de fichiers.
J'utilise un module de copie de modules de nœuds pour créer un fichier unique nécessitant tous les fichiers de notre système basé sur NodeJS.
Le code de notre fichier utilitaire ressemble à ceci:
/**
* Module dependencies.
*/
var copy = require('copy-to');
copy(require('./module1'))
.and(require('./module2'))
.and(require('./module3'))
.to(module.exports);
Dans tous les fichiers, la plupart des fonctions sont écrites comme des exportations, comme ceci:
exports.function1 = function () { // function contents };
exports.function2 = function () { // function contents };
exports.function3 = function () { // function contents };
Donc, pour utiliser n'importe quelle fonction d'un fichier, il suffit d'appeler:
var utility = require('./utility');
var response = utility.function2(); // or whatever the name of the function is
Développer cette glob
solution. Faites-le si vous souhaitez importer tous les modules d'un répertoire dans index.js
, puis l'importer index.js
dans une autre partie de l'application. Notez que les littéraux de modèle ne sont pas pris en charge par le moteur de mise en évidence utilisé par stackoverflow, le code peut donc sembler étrange ici.
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;
Exemple complet
Structure du répertoire
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 / inattendu.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';
Du projet à l'intérieur avec glob
installé , exécuteznode example.js
$ node example.js
foo ran
bar run
keepit ran unexpected
foo ran
bar run
keepit ran unexpected
Peut utiliser: https://www.npmjs.com/package/require-file-directory
Exiger tous les fichiers du routes
dossier et appliquer en tant que middleware. Aucun module externe requis.
// require
const path = require("path");
const { readdirSync } = require("fs");
// apply as middleware
readdirSync("./routes").map((r) => app.use("/api", require("./routes/" + r)));
En utilisant cette fonction, vous pouvez exiger un répertoire entier.
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);
Si vous incluez tous les fichiers de * .js dans l'exemple de répertoire ("app / lib / *. Js"):
example.js:
module.exports = function (example) { }
exemple-2.js:
module.exports = function (example2) { }
index.js:
module.exports = require('./app/lib');
var routes = require('auto-load')('routes');
avec le nouveauauto-load
module [j'ai aidé à le créer].