如果目录不存在,下面的方法是否正确?

它应该对脚本具有完全的权限,并且其他人可以阅读。

var dir = __dirname + '/upload';
if (!path.existsSync(dir)) {
    fs.mkdirSync(dir, 0744);
}

当前回答

mkdir方法能够递归地在一个路径中创建任何不存在的目录,并忽略存在的目录。

来自Node.js v10/11文档:

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

注意:首先需要导入内置的fs模块。

现在,这里有一个更健壮的例子,它利用了原生ECMAScript模块(启用了标志和.mjs扩展名),处理非根路径,并说明完整的路径名:

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

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

你可以像createDirectories('/components/widget/widget.js');一样使用它。

当然,当目录创建时,你可能想要在async/await中使用promises以一种更可读的同步方式来利用文件创建;但是,这超出了问题的范围。

其他回答

异步执行此操作的函数(从使用同步函数的SO上的类似答案调整,我现在找不到)

// ensure-directory.js
import { mkdir, access } from 'fs'

/**
 * directoryPath is a path to a directory (no trailing file!)
 */
export default async directoryPath => {
  directoryPath = directoryPath.replace(/\\/g, '/')

  // -- preparation to allow absolute paths as well
  let root = ''
  if (directoryPath[0] === '/') {
    root = '/'
    directoryPath = directoryPath.slice(1)
  } else if (directoryPath[1] === ':') {
    root = directoryPath.slice(0, 3) // c:\
    directoryPath = directoryPath.slice(3)
  }

  // -- create folders all the way down
  const folders = directoryPath.split('/')
  let folderPath = `${root}`
  for (const folder of folders) {
    folderPath = `${folderPath}${folder}/`

    const folderExists = await new Promise(resolve =>
      access(folderPath, error => {
        if (error) {
          resolve(false)
        }
        resolve(true)
      })
    )

    if (!folderExists) {
      await new Promise((resolve, reject) =>
        mkdir(folderPath, error => {
          if (error) {
            reject('Error creating folderPath')
          }
          resolve(folderPath)
        })
      )
    }
  }
}

下面是一个递归创建目录的小函数:

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
  }, '')
}

Use:

var filessystem = require('fs');
var dir = './path/subpath/';

if (!filessystem.existsSync(dir))
{
    filessystem.mkdirSync(dir);
}
else
{
    console.log("Directory already exist");
}

使用async / await:

const mkdirP = async (directory) => {
  try {
    return await fs.mkdirAsync(directory);
  } catch (error) {
    if (error.code != 'EEXIST') {
      throw e;
    }
  }
};

你需要承诺fs:

import nodeFs from 'fs';
import bluebird from 'bluebird';

const fs = bluebird.promisifyAll(nodeFs);

Fs.exist()已弃用。所以我使用fs.stat()来检查目录状态。如果目录不存在,fs.stat()抛出一个错误,并显示类似'没有这样的文件或目录'的消息。然后我创建了一个目录。

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

const dir = './dir';
fs.stat(dir).catch(async (err) => {
  if (err.message.includes('no such file or directory')) {
    await fs.mkdir(dir);
  }
});