How to create a directory if it doesn't exist using Node.js?

前端 未结 18 1068
臣服心动
臣服心动 2020-11-30 16:03

Is this the right way to create a directory if it doesn\'t exist. It should have full permission for the script and readable by others.

var dir = __dirname +         


        
相关标签:
18条回答
  • 2020-11-30 16:45

    I'd like to add a Typescript Promise refactor of josh3736's answer.

    It does the same thing and has the same edge cases, it just happens to use Promises, typescript typedefs and works with "use strict".

    // https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation
    const allRWEPermissions = parseInt("0777", 8);
    
    function ensureFilePathExists(path: string, mask: number = allRWEPermissions): Promise<void> {
        return new Promise<void>(
            function(resolve: (value?: void | PromiseLike<void>) => void,
                reject: (reason?: any) => void): void{
                mkdir(path, mask, function(err: NodeJS.ErrnoException): void {
                    if (err) {
                        if (err.code === "EEXIST") {
                            resolve(null); // ignore the error if the folder already exists
                        } else {
                            reject(err); // something else went wrong
                        }
                    } else {
                        resolve(null); // successfully created folder
                    }
                });
        });
    }
    
    0 讨论(0)
  • 2020-11-30 16:48

    You can just use mkdir and catch the error if the folder exists.
    This is async (so best practice) and safe.

    fs.mkdir('/path', err => { 
        if (err && err.code != 'EEXIST') throw 'up'
        .. safely do your stuff here  
        })
    

    (Optionally add a second argument with the mode.)


    Other thoughts:

    1. You could use then or await by using native promisify.

      const util = require('util'), fs = require('fs');
      const mkdir = util.promisify(fs.mkdir);
      var myFunc = () => { ..do something.. } 
      
      mkdir('/path')
          .then(myFunc)
          .catch(err => { if (err.code != 'EEXIST') throw err; myFunc() })
      
    2. You can make your own promise method, something like (untested):

      let mkdirAsync = (path, mode) => new Promise(
         (resolve, reject) => mkdir (path, mode, 
            err => (err && err.code !== 'EEXIST') ? reject(err) : resolve()
            )
         )
      
    3. For synchronous checking, you can use:

      fs.existsSync(path) || fs.mkdirSync(path)
      
    4. Or you can use a library, the two most popular being

      • mkdirp (just does folders)
      • fsextra (supersets fs, adds lots of useful stuff)
    0 讨论(0)
  • 2020-11-30 16:48

    Here is a little function to recursivlely create directories:

    const createDir = (dir) => {
      // This will create a dir given a path such as './folder/subfolder' 
      const splitPath = dir.split('/');
      splitPath.reduce((path, subPath) => {
        let currentPath;
        if(subPath != '.'){
          currentPath = path + '/' + subPath;
          if (!fs.existsSync(currentPath)){
            fs.mkdirSync(currentPath);
          }
        }
        else{
          currentPath = subPath;
        }
        return currentPath
      }, '')
    }
    
    0 讨论(0)
  • 2020-11-30 16:49

    You can use node File System command fs.stat to check if dir exists and fs.mkdir to create a directory with callback, or fs.mkdirSync to create a directory without callback, like this example:

    //first require fs
    const fs = require('fs');
    
    // Create directory if not exist (function)
    const createDir = (path) => {
        // check if dir exist
        fs.stat(path, (err, stats) => {
            if (stats.isDirectory()) {
                // do nothing
            } else {
                // if the given path is not a directory, create a directory
                fs.mkdirSync(path);
            }
        });
    };
    
    0 讨论(0)
  • 2020-11-30 16:50

    The mkdir method has the ability to recursively create any directories in a path that don't exist, and ignore the ones that do.

    From the Node v10/11 docs:

    // Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist.
    fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
        if (err) throw err;
    });
    

    NOTE: You'll need to import the built-in fs module first.

    Now here's a little more robust example that leverages native ES Modules (with flag enabled and .mjs extension), handles non-root paths, and accounts for full pathnames:

    import fs from 'fs';
    import path from 'path';
    
    createDirectories(pathname) {
       const __dirname = path.resolve();
       pathname = pathname.replace(/^\.*\/|\/?[^\/]+\.[a-z]+|\/$/g, ''); // Remove leading directory markers, and remove ending /file-name.extension
       fs.mkdir(path.resolve(__dirname, pathname), { recursive: true }, e => {
           if (e) {
               console.error(e);
           } else {
               console.log('Success');
           }
        });
    }
    

    You can use it like createDirectories('/components/widget/widget.js');.

    And of course, you'd probably want to get more fancy by using promises with async/await to leverage file creation in a more readable synchronous-looking way when the directories are created; but, that's beyond the question's scope.

    0 讨论(0)
  • 2020-11-30 16:50

    Just in case any one interested in the one line version. :)

    //or in typescript: import * as fs from 'fs';
    const fs = require('fs');
    !fs.existsSync(dir) && fs.mkdirSync(dir);
    
    0 讨论(0)
提交回复
热议问题