Как вы получаете список имен всех файлов, присутствующих в каталоге в Node.js?

979

Я пытаюсь получить список имен всех файлов, присутствующих в каталоге, используя Node.js. Я хочу вывод, который является массивом имен файлов. Как я могу это сделать?

resopollution
источник
9
fs.readdirработает, но не может использовать такие шаблоны имен файлов, как ls /tmp/*core*. Проверьте github.com/isaacs/node-glob . Глобусы могут даже искать в подкаталогах.
Джесс
Проверьте readdir-recursiveмодуль NPM, хотя, если вы ищете имена файлов в подкаталогах, также
Итан Дэвис
1
fs.readdir - это простое асинхронное решение - примеры здесь
drorw
Все еще не отвечаете, используя итератор? У меня есть 2,5 миллиона файлов для сканирования ... Я не хочу получать список 2,5 м пути через 10 минут.
Флавиен

Ответы:

1342

Вы можете использовать методы fs.readdirили fs.readdirSync.

fs.readdir

const testFolder = './tests/';
const fs = require('fs');

fs.readdir(testFolder, (err, files) => {
  files.forEach(file => {
    console.log(file);
  });
});

fs.readdirSync

const testFolder = './tests/';
const fs = require('fs');

fs.readdirSync(testFolder).forEach(file => {
  console.log(file);
});

Разница между этими двумя методами заключается в том, что первый метод является асинхронным, поэтому вы должны предоставить функцию обратного вызова, которая будет выполняться после завершения процесса чтения.

Второй является синхронным, он вернет массив имен файлов, но остановит дальнейшее выполнение вашего кода до завершения процесса чтения.

CMS
источник
204
Примечание: readdirтакже показывает имена каталогов . Чтобы отфильтровать их, используйте fs.stat(path, callback(err, stats))и stats.isDirectory().
Роб Вт
3
Я должен добавить, что, скорее всего, вам следует использовать readdire, потому что вы не хотите блокировать IO в узле.
DragonKnight
5
@ user3705055, если вы не используете gulp для чтения в каталоге файлов, зависящих от порядка исходного кода, и компиляции их в один исполняемый файл.
r3wt
2
@Sancarn Вы хотите попробовать разобрать вывод ls? Просто подождите, пока кто-нибудь не создаст имена файлов со встроенными пробелами и переводами строки ...
Радон Росборо
201

IMO самый удобный способ сделать такие задачи - использовать инструмент glob . Вот глобальный пакет для node.js. Установить с

npm install glob

Затем используйте подстановочный знак для сопоставления имен файлов (пример взят с сайта пакета)

var glob = require("glob")

// options is optional
glob("**/*.js", options, function (er, files) {
  // files is an array of filenames.
  // If the `nonull` option is set, and nothing
  // was found, then files is ["**/*.js"]
  // er is an error object or null.
})
КЛС
источник
5
это было лучшее решение для меня, так как я хотел указать тип файла проще, чем сравнение строк. Спасибо.
Погриндис
Мне это тоже нравится только потому, что глобблинг - это почти фундаментальный навык в ноде. Если вы хотите просто вернуть имена файлов, передайте a cwdв объекте параметров.
jcollum
1
Как можно получить результаты globвне себя? Например. Я хочу console.logрезультатов, но не внутри glob()?
Ланти
14
@Lanti: glob.sync(pattern, [options])метод может быть проще в использовании, поскольку он просто возвращает массив имен файлов, а не использует обратный вызов. Более подробная информация здесь: github.com/isaacs/node-glob
Гленн Лоуренс
2
Для тех, кто, как я, ищет глобальную реализацию с помощью Promises, ознакомьтесь с globby от sindresorhus: github.com/sindresorhus/globby
Nacho Coloma,
180

Ответ выше не выполняет рекурсивный поиск в каталоге. Вот что я сделал для рекурсивного поиска ( с помощью узла-гуляет : npm install walk)

var walk    = require('walk');
var files   = [];

// Walker options
var walker  = walk.walk('./test', { followLinks: false });

walker.on('file', function(root, stat, next) {
    // Add this file to the list of files
    files.push(root + '/' + stat.name);
    next();
});

walker.on('end', function() {
    console.log(files);
});
Рубен Тан
источник
4
fs.readdirSync лучше, нативная альтернатива, созданная специально для этого.
Eraden
37
К сожалению, fs.readdirSync не входит в подкаталоги, если только вы не захотите написать свою собственную подпрограмму, чтобы сделать именно это, чего вы не сделали, учитывая, что уже существуют модули npm для решения этой самой проблемы.
Рубен Тан
6
Вот ссылка на репозиторий Walk GitHub + документы: github.com/coolaj86/node-walk
santiagoIT
OP не спрашивал, какой API выполняет рекурсивное чтение. В любом случае принятый ответ дает то, что также может служить основанием для рекурсивного чтения.
Игве Калу
Это фантастическая функция. Быстрый вопрос: есть ли быстрый способ игнорировать определенные каталоги? Я хочу игнорировать каталоги, начинающиеся с.git
j_d
91

Получить файлы во всех подкаталогах

function getFiles (dir, files_){
    files_ = files_ || [];
    var files = fs.readdirSync(dir);
    for (var i in files){
        var name = dir + '/' + files[i];
        if (fs.statSync(name).isDirectory()){
            getFiles(name, files_);
        } else {
            files_.push(name);
        }
    }
    return files_;
}

console.log(getFiles('path/to/dir'))
Tito100
источник
4
Почему if (typeof files_ === 'undefined') files_=[];? вам нужно только сделать var files_ = files_ || [];вместо files_ = files_ || [];.
Jkutianski
4
Вы забыли добавить var fs = require('fs');в начале getFiles.
GFoley83
Это рекурсивный метод. Он не поддерживает очень глубокие структуры папок, что приведет к переполнению стека.
Матиас Ликкегор Лоренцен
63

Вот простое решение с использованием только нативного модуля fsи pathмодулей:

// sync version
function walkSync(currentDirPath, callback) {
    var fs = require('fs'),
        path = require('path');
    fs.readdirSync(currentDirPath).forEach(function (name) {
        var filePath = path.join(currentDirPath, name);
        var stat = fs.statSync(filePath);
        if (stat.isFile()) {
            callback(filePath, stat);
        } else if (stat.isDirectory()) {
            walkSync(filePath, callback);
        }
    });
}

или асинхронная версия (используется fs.readdirвместо):

// async version with basic error handling
function walk(currentDirPath, callback) {
    var fs = require('fs'),
        path = require('path');
    fs.readdir(currentDirPath, function (err, files) {
        if (err) {
            throw new Error(err);
        }
        files.forEach(function (name) {
            var filePath = path.join(currentDirPath, name);
            var stat = fs.statSync(filePath);
            if (stat.isFile()) {
                callback(filePath, stat);
            } else if (stat.isDirectory()) {
                walk(filePath, callback);
            }
        });
    });
}

Тогда вы просто звоните (для синхронизации версии):

walkSync('path/to/root/dir', function(filePath, stat) {
    // do something with "filePath"...
});

или асинхронная версия:

walk('path/to/root/dir', function(filePath, stat) {
    // do something with "filePath"...
});

Разница в том, как блокирует узлы при выполнении ввода-вывода. Учитывая, что API выше, то же самое, вы можете просто использовать асинхронную версию, чтобы обеспечить максимальную производительность.

Однако есть одно преимущество использования синхронной версии. Некоторый код легче выполнить, как только завершится обход, как в следующем операторе после обхода. В асинхронной версии вам понадобится дополнительный способ узнать, когда вы закончите. Возможно, сначала создайте карту всех путей, а затем перечислите их. Для простых сценариев сборки / утилит (против высокопроизводительных веб-серверов) вы можете использовать синхронизирующую версию без какого-либо ущерба.

Али
источник
1
Если заменить строку в walkSyncс walk(filePath, callback);кwalkSync(filePath, callback);
MIDE11
3
Но вы все еще используете fs.statSync, который блокирует, в асинхронной версии. Разве вы не должны использовать вместо этого fs.stat?
MindlessRanger
Это действительно полезно, и этот метод является рекурсивным. Спасибо!
Литл-Ройс
35

Начиная с Node v10.10.0, можно использовать новую withFileTypesопцию для fs.readdirи fs.readdirSyncв сочетании с dirent.isDirectory()функцией для фильтрации имен файлов в каталоге. Это выглядит так:

fs.readdirSync('./dirpath', {withFileTypes: true})
.filter(item => !item.isDirectory())
.map(item => item.name)

Возвращенный массив имеет вид:

['file1.txt', 'file2.txt', 'file3.txt']

Документы для класса fs.Dirent

bnp887
источник
7
Пока что это лучший ответ здесь!
Алексей Ивасёв
2
это то, что люди ищут в 2020 году - надо «приколоться»
Вал Редченко
1
Лучший ответ 2020!
Ив Ланге
26

Использование обещаний с ES7

Асинхронное использование с mz / fs

mzМодуль обеспечивает promisified версии библиотеки ядра узла. Использовать их просто. Сначала установите библиотеку ...

npm install mz

Затем...

const fs = require('mz/fs');
fs.readdir('./myDir').then(listing => console.log(listing))
  .catch(err => console.error(err));

В качестве альтернативы вы можете написать их в асинхронных функциях в ES7:

async function myReaddir () {
  try {
    const file = await fs.readdir('./myDir/');
  }
  catch (err) { console.error( err ) }
};

Обновление для рекурсивного листинга

Некоторые пользователи указали желание увидеть рекурсивный список (хотя и не в вопросе) ... Использовать fs-promise. Это тонкая обертка вокруг mz.

npm install fs-promise;

тогда...

const fs = require('fs-promise');
fs.walk('./myDir').then(
    listing => listing.forEach(file => console.log(file.path))
).catch(err => console.error(err));
Эван Кэрролл
источник
5
fs.walk удален из fs-обещания, так как он не поддерживается fs ( github.com/kevinbeaty/fs-promise/issues/28 )
adnan
20

Зависимости.

var fs = require('fs');
var path = require('path');

Определение.

// String -> [String]
function fileList(dir) {
  return fs.readdirSync(dir).reduce(function(list, file) {
    var name = path.join(dir, file);
    var isDir = fs.statSync(name).isDirectory();
    return list.concat(isDir ? fileList(name) : [name]);
  }, []);
}

Применение.

var DIR = '/usr/local/bin';

// 1. List all files in DIR
fileList(DIR);
// => ['/usr/local/bin/babel', '/usr/local/bin/bower', ...]

// 2. List all file names in DIR
fileList(DIR).map((file) => file.split(path.sep).slice(-1)[0]);
// => ['babel', 'bower', ...]

Обратите внимание, что fileListэто слишком оптимистично. Для чего-то серьезного, добавьте обработку ошибок.

Унан Ростомян
источник
1
Я также добавил excludeDirsаргумент массива. Это меняет его настолько, что, возможно, вы должны отредактировать его (если хотите). В противном случае я добавлю это в другом ответе. gist.github.com/AlecTaylor/f3f221b4fb86b4375650
AT
1
@AT Хорошо! Вы должны опубликовать свой собственный ответ, так как это полезное расширение. Давайте оставим этот безликим.
Унан Ростомян
19

нерекурсивная версия

Вы не говорите, что хотите сделать это рекурсивно, поэтому я предполагаю, что вам нужны только прямые дочерние элементы каталога.

Образец кода:

const fs = require('fs');
const path = require('path');

fs.readdirSync('your-directory-path')
  .filter((file) => fs.lstatSync(path.join(folder, file)).isFile());
Тайлер Лонг
источник
10

Загрузить fs:

const fs = require('fs');

Чтение файлов асинхронно :

fs.readdir('./dir', function (err, files) {
    // "files" is an Array with files names
});

Синхронизация файлов чтения :

var files = fs.readdirSync('./dir');
Эдуардо Куомо
источник
10

если кто-то все еще ищет это, я делаю это:

import fs from 'fs';
import path from 'path';

const getAllFiles = dir =>
    fs.readdirSync(dir).reduce((files, file) => {
        const name = path.join(dir, file);
        const isDirectory = fs.statSync(name).isDirectory();
        return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name];
    }, []);

и его работа очень хорошо для меня

мистифицировать
источник
Отлично сработало для меня И это рекурсивно. Просто помните, что синтаксис импорта по-прежнему стоит за флагом в Node, возможно, вам придется пойти по старому пути: const fs = require ('fs');
mjsarfatti
@ Джош Это работает как шарм. Тем не менее, с трудом понять, как [...files, ...getAllFiles(name)]или [...files, name]работает. Небольшое объяснение было бы очень полезно :)
Md Mazedul Islam Khan
1
@MdMazedulIslamKhan ...Используемый здесь называется синтаксис распространения. По сути, он берет все объекты внутри массива и «распространяет» его в новый массив. В этом случае все записи в filesмассиве добавляются в возвращаемое значение вместе со всеми значениями, возвращаемыми из рекурсивного вызова. Вы можете обратиться к синтаксису распространения здесь: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
T90
8

Получить sortedимена файлов. Вы можете отфильтровать результаты по конкретному, extensionнапример '.txt', '.jpg'и так далее.

import * as fs from 'fs';
import * as Path from 'path';

function getFilenames(path, extension) {
    return fs
        .readdirSync(path)
        .filter(
            item =>
                fs.statSync(Path.join(path, item)).isFile() &&
                (extension === undefined || Path.extname(item) === extension)
        )
        .sort();
}
Яс
источник
6

Из вашего вопроса я предполагаю, что вам не нужны имена каталогов, только файлы.

Пример:

animals
├── all.jpg
├── mammals
   └── cat.jpg
   └── dog.jpg
└── insects
    └── bee.jpg

Если вы хотите просто массив путей к файлам, используйте return_object: false:

const fs = require('fs').promises;
const path = require('path');

async function walk(dir) {
    let files = await fs.readdir(dir);
    files = await Promise.all(files.map(async file => {
        const filePath = path.join(dir, file);
        const stats = await fs.stat(filePath);
        if (stats.isDirectory()) return walk(filePath);
        else if(stats.isFile()) return filePath;
    }));

    return files.reduce((all, folderContents) => all.concat(folderContents), []);
}

console.log(walk('animals'))

возвращает:

[
  "/animals/all.jpg",
  "/animals/mammals/cat.jpg",
  "/animals/mammals/dog.jpg",
  "/animals/insects/bee.jpg"
];

Кредиты перейти на https://gist.github.com/lovasoa/8691344#gistcomment-2927279

a.barbieri
источник
5

Вот асинхронная рекурсивная версия.

    function ( path, callback){
     // the callback gets ( err, files) where files is an array of file names
     if( typeof callback !== 'function' ) return
     var
      result = []
      , files = [ path.replace( /\/\s*$/, '' ) ]
     function traverseFiles (){
      if( files.length ) {
       var name = files.shift()
       fs.stat(name, function( err, stats){
        if( err ){
         if( err.errno == 34 ) traverseFiles()
    // in case there's broken symbolic links or a bad path
    // skip file instead of sending error
         else callback(err)
        }
        else if ( stats.isDirectory() ) fs.readdir( name, function( err, files2 ){
         if( err ) callback(err)
         else {
          files = files2
           .map( function( file ){ return name + '/' + file } )
           .concat( files )
          traverseFiles()
         }
        })
        else{
         result.push(name)
         traverseFiles()
        }
       })
      }
      else callback( null, result )
     }
     traverseFiles()
    }
Огги Трансфлюкситор Джонс
источник
4
Получите привычку добавлять точки с запятой в конце ваших утверждений. В противном случае вы не можете минимизировать код. Тем не менее, спасибо за столь необходимый асинхронный вклад.
user2867288
2
ХАХАХАХА, это не часть спецификации, просто какой-то случайный человек, называющий свой любимый стиль линтинга «стандартными». Точки с запятой являются хорошей практикой, особенно в Javascript, для обеспечения ясности кода. В противном случае вы и ваша команда должны запомнить правила автоматической вставки точек с запятой , и я знаю, что, по крайней мере, средний разработчик JS, в котором я работаю, не настолько прилежен.
user2867288
@ user2867288 Но поскольку ASI существует, мы можем его использовать, нет? Я использую eslint и prettier для регулярного форматирования кода при сохранении, и вставка точек с запятой не является проблемой.
Дуира
5

Взял общий подход @ Унаня-Ростомяна, сделал его немного более сжатым и добавил excludeDirsаргумент. Это было бы тривиально includeDirs, просто следуйте той же схеме:

import * as fs from 'fs';
import * as path from 'path';

function fileList(dir, excludeDirs?) {
    return fs.readdirSync(dir).reduce(function (list, file) {
        const name = path.join(dir, file);
        if (fs.statSync(name).isDirectory()) {
            if (excludeDirs && excludeDirs.length) {
                excludeDirs = excludeDirs.map(d => path.normalize(d));
                const idx = name.indexOf(path.sep);
                const directory = name.slice(0, idx === -1 ? name.length : idx);
                if (excludeDirs.indexOf(directory) !== -1)
                    return list;
            }
            return list.concat(fileList(name, excludeDirs));
        }
        return list.concat([name]);
    }, []);
}

Пример использования:

console.log(fileList('.', ['node_modules', 'typings', 'bower_components']));
В
источник
У меня есть основная папка: scss, а внутри нее другая папка: темы, но в итоговом списке отображаются все каталоги, а не только каталоги без каталога исключений, что происходит?
SalahAdDin
Работает только с '.' папка directory, с остальными каталогами не работает.
SalahAdDin
5

Из коробки

В случае, если вам нужен объект со структурой каталогов из коробки, я настоятельно рекомендую вам проверить дерево каталогов .

Допустим, у вас есть эта структура:

photos
   june
   └── windsurf.jpg
└── january
    ├── ski.png
    └── snowboard.jpg
const dirTree = require("directory-tree");
const tree = dirTree("/path/to/photos");

Вернусь:

{
  path: "photos",
  name: "photos",
  size: 600,
  type: "directory",
  children: [
    {
      path: "photos/june",
      name: "june",
      size: 400,
      type: "directory",
      children: [
        {
          path: "photos/june/windsurf.jpg",
          name: "windsurf.jpg",
          size: 400,
          type: "file",
          extension: ".jpg"
        }
      ]
    },
    {
      path: "photos/january",
      name: "january",
      size: 200,
      type: "directory",
      children: [
        {
          path: "photos/january/ski.png",
          name: "ski.png",
          size: 100,
          type: "file",
          extension: ".png"
        },
        {
          path: "photos/january/snowboard.jpg",
          name: "snowboard.jpg",
          size: 100,
          type: "file",
          extension: ".jpg"
        }
      ]
    }
  ]
}

Пользовательский объект

В противном случае, если вы хотите создать объект дерева каталогов с вашими пользовательскими настройками , взгляните на следующий фрагмент. Живой пример виден на этом коде .

// my-script.js
const fs = require("fs");
const path = require("path");

const isDirectory = filePath => fs.statSync(filePath).isDirectory();
const isFile = filePath => fs.statSync(filePath).isFile();

const getDirectoryDetails = filePath => {
  const dirs = fs.readdirSync(filePath);
  return {
    dirs: dirs.filter(name => isDirectory(path.join(filePath, name))),
    files: dirs.filter(name => isFile(path.join(filePath, name)))
  };
};

const getFilesRecursively = (parentPath, currentFolder) => {
  const currentFolderPath = path.join(parentPath, currentFolder);
  let currentDirectoryDetails = getDirectoryDetails(currentFolderPath);

  const final = {
    current_dir: currentFolder,
    dirs: currentDirectoryDetails.dirs.map(dir =>
      getFilesRecursively(currentFolderPath, dir)
    ),
    files: currentDirectoryDetails.files
  };

  return final;
};

const getAllFiles = relativePath => {
  const fullPath = path.join(__dirname, relativePath);
  const parentDirectoryPath = path.dirname(fullPath);
  const leafDirectory = path.basename(fullPath);

  const allFiles = getFilesRecursively(parentDirectoryPath, leafDirectory);
  return allFiles;
};

module.exports = { getAllFiles };

Тогда вы можете просто сделать:

// another-file.js 

const { getAllFiles } = require("path/to/my-script");

const allFiles = getAllFiles("/path/to/my-directory");
Махеш
источник
3

Это TypeScript, опционально рекурсивный, опционально протоколирование ошибок и асинхронное решение. Вы можете указать регулярное выражение для имен файлов, которые вы хотите найти.

Я использовал fs-extra, потому что это легкий супер набор улучшений fs.

import * as FsExtra from 'fs-extra'

/**
 * Finds files in the folder that match filePattern, optionally passing back errors .
 * If folderDepth isn't specified, only the first level is searched. Otherwise anything up
 * to Infinity is supported.
 *
 * @static
 * @param {string} folder The folder to start in.
 * @param {string} [filePattern='.*'] A regular expression of the files you want to find.
 * @param {(Error[] | undefined)} [errors=undefined]
 * @param {number} [folderDepth=0]
 * @returns {Promise<string[]>}
 * @memberof FileHelper
 */
public static async findFiles(
    folder: string,
    filePattern: string = '.*',
    errors: Error[] | undefined = undefined,
    folderDepth: number = 0
): Promise<string[]> {
    const results: string[] = []

    // Get all files from the folder
    let items = await FsExtra.readdir(folder).catch(error => {
        if (errors) {
            errors.push(error) // Save errors if we wish (e.g. folder perms issues)
        }

        return results
    })

    // Go through to the required depth and no further
    folderDepth = folderDepth - 1

    // Loop through the results, possibly recurse
    for (const item of items) {
        try {
            const fullPath = Path.join(folder, item)

            if (
                FsExtra.statSync(fullPath).isDirectory() &&
                folderDepth > -1)
            ) {
                // Its a folder, recursively get the child folders' files
                results.push(
                    ...(await FileHelper.findFiles(fullPath, filePattern, errors, folderDepth))
                )
            } else {
                // Filter by the file name pattern, if there is one
                if (filePattern === '.*' || item.search(new RegExp(filePattern, 'i')) > -1) {
                    results.push(fullPath)
                }
            }
        } catch (error) {
            if (errors) {
                errors.push(error) // Save errors if we wish
            }
        }
    }

    return results
}
Пол Ф. Вуд
источник
1

Это сработает и сохранит результат в файле test.txt, который будет находиться в том же каталоге

  fs.readdirSync(__dirname).forEach(file => {
    fs.appendFileSync("test.txt", file+"\n", function(err){
    })
})
Рама
источник
1

Я недавно создал для этого инструмент, который делает именно это ... Он выбирает каталог асинхронно и возвращает список элементов. Вы можете получить каталоги, файлы или и то и другое, причем папки будут первыми. Вы также можете разбивать данные на страницы, если вы не хотите извлекать всю папку.

https://www.npmjs.com/package/fs-browser

Это ссылка, надеюсь, она кому-нибудь поможет!

stefantigro
источник
0

Просто наперед: если вы планируете выполнять операции с каждым файлом в каталоге, попробуйте винил-fs (который используется gulp , системой потоковой сборки).

XåpplI'-I0llwlg'I -
источник
0

Я сделал модуль узла для автоматизации этой задачи: mddir

Применение

узел mddir "../relative/path/"

Для установки: npm установите mddir -g

Чтобы создать уценку для текущего каталога: mddir

Генерировать для любого абсолютного пути: mddir / absolute / path

Чтобы сгенерировать относительный путь: mddir ~ / Documents / what.

MD-файл генерируется в вашем рабочем каталоге.

В настоящее время игнорирует node_modules и папки .git.

Поиск проблемы

Если вы получаете сообщение об ошибке «узел \ r: нет такого файла или каталога», проблема заключается в том, что ваша операционная система использует разные окончания строк, и mddir не сможет их проанализировать без явного задания стиля окончания строк в Unix. Обычно это влияет на Windows, но также и на некоторые версии Linux. Установка конца строки в стиле Unix должна выполняться в глобальной папке bin mddir npm.

Исправление концов строки

Получить путь к папке npm bin с помощью:

npm config get prefix

Компакт-диск в эту папку

заварить установить dos2unix

dos2unix lib / node_modules / mddir / src / mddir.js

Это преобразует окончания строк в Unix вместо Dos

Затем запустите как обычно с: node mddir "../relative/path/".

Пример сгенерированной структуры файла уценки 'directoryList.md'

    |-- .bowerrc
    |-- .jshintrc
    |-- .jshintrc2
    |-- Gruntfile.js
    |-- README.md
    |-- bower.json
    |-- karma.conf.js
    |-- package.json
    |-- app
        |-- app.js
        |-- db.js
        |-- directoryList.md
        |-- index.html
        |-- mddir.js
        |-- routing.js
        |-- server.js
        |-- _api
            |-- api.groups.js
            |-- api.posts.js
            |-- api.users.js
            |-- api.widgets.js
        |-- _components
            |-- directives
                |-- directives.module.js
                |-- vendor
                    |-- directive.draganddrop.js
            |-- helpers
                |-- helpers.module.js
                |-- proprietary
                    |-- factory.actionDispatcher.js
            |-- services
                |-- services.cardTemplates.js
                |-- services.cards.js
                |-- services.groups.js
                |-- services.posts.js
                |-- services.users.js
                |-- services.widgets.js
        |-- _mocks
            |-- mocks.groups.js
            |-- mocks.posts.js
            |-- mocks.users.js
            |-- mocks.widgets.js
Джон Бирн
источник
0

Используйте модуль npm списка содержимого . Он читает содержимое и под-содержимое данного каталога и возвращает список путей к файлам и папкам.

const list = require('list-contents');

list("./dist",(o)=>{
  if(o.error) throw o.error;
   console.log('Folders: ', o.dirs);
   console.log('Files: ', o.files);
});
Paweł
источник
-1
function getFilesRecursiveSync(dir, fileList, optionalFilterFunction) {
    if (!fileList) {
        grunt.log.error("Variable 'fileList' is undefined or NULL.");
        return;
    }
    var files = fs.readdirSync(dir);
    for (var i in files) {
        if (!files.hasOwnProperty(i)) continue;
        var name = dir + '/' + files[i];
        if (fs.statSync(name).isDirectory()) {
            getFilesRecursiveSync(name, fileList, optionalFilterFunction);
        } else {
            if (optionalFilterFunction && optionalFilterFunction(name) !== true)
                continue;
            fileList.push(name);
        }
    }
}
Francois
источник