node.js yêu cầu tất cả các tệp trong một thư mục?


330

Làm cách nào để tôi yêu cầu tất cả các tệp trong một thư mục trong node.js?

cần một cái gì đó như:

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

4
var routes = require('auto-load')('routes');với auto-loadmô-đun mới [Tôi đã giúp tạo ra nó].
Francisco Presencia

Câu trả lời:


515

Khi yêu cầu được đưa ra đường dẫn của một thư mục, nó sẽ tìm tệp index.js trong thư mục đó; nếu có, nó sử dụng cái đó và nếu không, nó sẽ thất bại.

Có lẽ sẽ có ý nghĩa nhất (nếu bạn có quyền kiểm soát thư mục) để tạo tệp index.js và sau đó gán tất cả "mô-đun" và sau đó chỉ cần yêu cầu điều đó.

yourfile.js

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

index.js

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

Nếu bạn không biết tên tập tin, bạn nên viết một số loại trình tải.

Ví dụ làm việc của trình nạp:

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

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

// Continue application logic here

152
Để thêm một số làm rõ: Khi requiređược đưa ra đường dẫn của một thư mục, nó sẽ tìm một index.jstrong thư mục đó; nếu có, nó sử dụng cái đó và nếu không, nó sẽ thất bại. Xem github.com/christkv/node-mongodb-native để biết ví dụ thực tế về điều này: Có một index.jsthư mục gốc yêu cầu ./lib/mongodb, một thư mục; ./lib/mongodb/index.js'làm cho mọi thứ khác trong thư mục đó có sẵn.
Trevor Burnham

22
requirelà một chức năng đồng bộ nên không có lợi ích từ gọi lại. Tôi sẽ sử dụng fs.readdirSync thay thế.
Rafał Sobota

4
Cảm ơn, đã gặp vấn đề tương tự ngày hôm nay và nghĩ rằng "tại sao không có yêu cầu ('./ tuyến / *')?".
Richard Clayton

3
@RobertMartin thật hữu ích khi bạn không cần xử lý bất cứ thứ gì được xuất; chẳng hạn, nếu tôi chỉ muốn truyền một thể hiện ứng dụng Express cho một tập hợp các tệp sẽ liên kết các tuyến.
Richard Clayton

2
@TrevorBurnham Để thêm, tệp chính (tức là tệp index.js) của một thư mục có thể được thay đổi thông qua package.jsontrong thư mục này. Giống như vậy:{main: './lib/my-custom-main-file.js'}
chống độc

187

Tôi khuyên bạn nên sử dụng toàn cầu để hoàn thành nhiệm vụ đó.

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

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

12
Mọi người nên sử dụng câu trả lời này;)
Jamie Hutber 5/07/2015

2
Câu trả lời tốt nhất! Dễ dàng hơn tất cả các tùy chọn khác, đặc biệt là đối với các thư mục con đệ quy có tệp bạn cần đưa vào.
ngDeveloper

1
Đề xuất toàn cầu do kiểm soát tổng thể mà bạn có đối với các bộ tiêu chí tệp tin bạn có thể chỉ định.
stephenwil

6
glob? bạn có ý nghĩa glob-savior-of-the-nodejs-race. Câu trả lời tốt nhất.
đào sâu

3
Sử dụng map () để lưu các liên kết: const tuyến = contin.sync ('./ tuyến / ** / *. Js'). Map (tệp => Yêu cầu (path.resolve (tệp)));
lexa-b

71

Dựa trên giải pháp của @ tbranyen, tôi tạo một index.jstệp tải các javascripts tùy ý trong thư mục hiện tại như một phần của 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);
  }
});

Sau đó, bạn có thể requirethư mục này từ bất cứ nơi nào khác.


5
Tôi biết điều này đã hơn một năm tuổi, nhưng bạn thực sự có thể yêu cầu các tệp JSON, vì vậy có lẽ một cái gì đó như thế /\.js(on)?$/sẽ tốt hơn. Cũng không !== nulldư thừa?

59

Một tùy chọn khác là sử dụng gói request-dir để bạn thực hiện các thao tác sau. Nó hỗ trợ đệ quy là tốt.

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

3
+1 require-dirvì nó tự động loại trừ tệp gọi (chỉ mục) và mặc định cho thư mục hiện tại. Hoàn hảo.
biofractal

2
Trong npm có một vài gói tương tự khác: request-all, request-thư mục, request-dir và các gói khác. Tải xuống nhiều nhất dường như là bắt buộc tất cả, ít nhất là vào tháng 7 năm 2015.
Mnebuerquo

request-dir hiện được tải xuống nhiều nhất (nhưng đáng chú ý là nó không hỗ trợ loại trừ tệp tại thời điểm viết)
Sean Anderson

Ba năm sau bình luận của Sean ở trên, require-dirđã thêm một filtertùy chọn.
tặng quà

7

Tôi có một thư mục / trường chứa đầy các tệp với một lớp duy nhất, ví dụ:

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

Bỏ cái này vào các trường / index.js để xuất từng lớp:

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

Điều này làm cho các mô-đun hoạt động giống như trong Python:

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

6

Một tùy chọn nữa là các tính năng kết hợp bắt buộc-dir-all từ hầu hết các gói phổ biến.

Phổ biến nhất require-dirkhông có tùy chọn để lọc các tệp / thư mục và không có mapchức năng (xem bên dưới), nhưng sử dụng mẹo nhỏ để tìm đường dẫn hiện tại của mô-đun.

Thứ hai bởi sự phổ biến require-allcó bộ lọc tiền xử lý và tiền xử lý, nhưng thiếu đường dẫn tương đối, vì vậy bạn cần sử dụng __dirname(điều này có ưu và nhược điểm) như:

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

Đề cập ở đây require-indexlà khá tối giản.

Với mapbạn có thể thực hiện một số tiền xử lý, như tạo các đối tượng và chuyển các giá trị cấu hình (giả sử các mô-đun bên dưới các hàm tạo):

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

Tôi biết câu hỏi này đã hơn 5 năm tuổi và các câu trả lời đã cho là tốt, nhưng tôi muốn một cái gì đó mạnh mẽ hơn một chút để thể hiện, vì vậy tôi đã tạo ra express-map2gói cho npm. Tôi sẽ đặt tên đơn giản express-map, tuy nhiên những người ở yahoo đã có một gói với tên đó, vì vậy tôi phải đổi tên gói của mình.

1. cách sử dụng cơ bản:

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

sử dụng bộ điều khiển:

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

};

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

    foo: function(req,res){

    },

    bar: function(req,res){

    }

};

2. sử dụng nâng cao, với tiền tố:

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

Như bạn có thể thấy, điều này giúp tiết kiệm rất nhiều thời gian và làm cho việc định tuyến ứng dụng của bạn trở nên đơn giản để viết, duy trì và hiểu. nó hỗ trợ tất cả các động từ http thể hiện sự hỗ trợ, cũng như .all()phương thức đặc biệt .


3

Một mô-đun mà tôi đã sử dụng cho trường hợp sử dụng chính xác này là bắt buộc .

Nó đệ quy yêu cầu tất cả các tệp trong một thư mục nhất định và các thư mục con của nó miễn là chúng không khớp với thuộc excludeDirstính.

Nó cũng cho phép chỉ định bộ lọc tệp và cách lấy các khóa của hàm băm được trả về từ tên tệp.


2

Tôi đang sử dụng mô-đun nút sao chép mô-đun để tạo một tệp duy nhất để yêu cầu tất cả các tệp trong hệ thống dựa trên NodeJS của chúng tôi.

Mã cho tệp tiện ích của chúng tôi trông như thế này:

/**
 * Module dependencies.
 */

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

Trong tất cả các tệp, hầu hết các hàm được viết dưới dạng xuất, như vậy:

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

Vì vậy, sau đó để sử dụng bất kỳ chức năng nào từ một tệp, bạn chỉ cần gọi:

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

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

2

Mở rộng về giải pháp này glob . Làm điều này nếu bạn muốn nhập tất cả các mô-đun từ một thư mục vào index.jsvà sau đó nhập nó index.jstrong một phần khác của ứng dụng. Lưu ý rằng các mẫu chữ không được hỗ trợ bởi công cụ tô sáng được sử dụng bởi stackoverflow để mã có thể trông lạ ở đây.

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;

Ví dụ đầy đủ

Cấu trúc thư mục

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

globalExample / 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

globalExample / 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;

globalExample / foobars / yet.js

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

globalExample / foobars / barit.js

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

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

globalExample / foobars / fooit.js

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

Từ dự án bên trong với glob cài đặt , chạynode example.js

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


1

Yêu cầu tất cả các tệp từ routesthư mục và áp dụng như phần mềm trung gian. Không có mô-đun bên ngoài cần thiết.

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

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

0

Sử dụng chức năng này, bạn có thể yêu cầu toàn bộ thư mục.

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

Nếu bạn bao gồm tất cả các tệp của * .js trong ví dụ thư mục ("app / lib / *. Js"):

Trong thư mục ứng dụng / lib

example.js:

module.exports = function (example) { }

ví dụ-2.js:

module.exports = function (example2) { }

Trong thư mục ứng dụng tạo index.js

index.js:

module.exports = require('./app/lib');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.