2

Reading directories recursivly is not the problem. There are many good libraries for it, for instance recursive-readdir.

I am searching for a solution to extract only the folder structure without any files etc.

Example folder structure:

src/app/_content
├── contact.md
├── disclaimer.md
├── imprint.md
├── index.md
├── news.md
├── vita.md
└── work
    ├── drawing
    │   └── Z-WV-2018-001
    │       ├── index.md
    │       └── Z-WV-2018-001-0.jpeg
    └── sculpture
        └── EMPTY DIRECTORY

The wished output is an array like that:

const dirs = [
  'work',
  'work/drawing',
  'work/sculpture'
]

Further Information: The following part is not explicitly part of that question. This will be an additional part for a better understand of the problem deep in the back of my brain.

This should not be that hard, but in addition I will need to extract in the second step an object like this:

const files = [
  'content.md',
  'disclaimer.md',
  'imprint.md',
  'index.md',
  'news.md',
  'vita.md',
  {
    'work': [
      {
        'drawing': [
          {
            'Z-WV-2018-001': [
              'index.md',
              'Z-WV-2018-001-0.jpeg'
            ],
          },
          {
            'sculpture': []
          }
        ]
      }
    ]
  }
]

dirs will be needed for a browser application to know the pathes to the files. files will be neded to get the corresponding files out of the directories.

For clarification, I am building a static page generator with Angular 6 and it is not possible to read client-sidely the folder structure. Therefore it is necessary to compile that structure and put it with an nodejs script into the published folder. So Angular will know where to look for that files.

Please write a comment, if you need more clarification. I just wanted to be exact as possible.

3 Answers 3

1

The library you provided gives you the ability to customize what it ignores during its search. You should be able to do something like this (disclaimer: haven't tested this):

const recursive = require("recursive-readdir");

function ignoreFiles(file, stats) {
  return !stats.isDirectory();
}

recursive("some/path", [ignoreFiles], function (err, dirs) {
  console.log(dirs);
});
Sign up to request clarification or add additional context in comments.

4 Comments

So clever. I did not realize to use a method instead of an array.
Could you explain the syntax, please? I anticipate you've looked into the type defenitions of that library, found the IgnoreFunction and so on. But why you have not to provide any arguments inside recursive for the ignoreFIles method?
The recursive function takes in an array of 'ignore' variables (in my example this is [ignoreFiles]). You can pass in strings or functions to this ignore array. If you pass in a string, it will ignore all files that match that string pattern. If you pass in a function, then that function will be called with the file object as the argument (and some more information in stats). If the function returns true then the file will be ignored by the search, otherwise it will be included.
Nevertheless this is not the solution for that problem. Although ignoreFiles() could filter the directories, the module recursive-readdir will not be able to give the wanted output. It focuses natively on the files and not on the folders. Did you tried to test your code?
1

You can use fs.stat method or it's synchronous version: fs.statSync. The method returns a fs.Stats instance. fs.Stats instances have .isDirectory method which returns true when a path is a directory.

const fs = require('fs');
fs.stat('/pathname', (err, stats) => {
    if (err) throw err;
    const isDir = stats.isDirectory();
    // ...
});

You need to call the fs.stat function for each pathname.

If using a library is an option, you can also use the draxt package:

const $ = require('draxt');
(async() {
   const $app = await $('src/app/_content/**');
   const $dirs = $app.directories();
   // dirs is a draxt collection of directories
   const dirPaths = $dirs.map(el => el.pathName);
   // dirPaths is an array of directories' absolute pathNames
}());

Comments

0
const klawSync = require('klaw-sync')
const dir = 'src/app/_content'
const files = klawSync(dir, {
  nofile: true
})

console.log(files.map(item => {
  return item.path.slice(item.path.indexOf(dir) + dir.length + 1)
}))

There will be a native solution for that problem for sure, but I decided to solve it with the help of an external module klaw-sync.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.