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

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

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以一种更可读的同步方式来利用文件创建;但是,这超出了问题的范围。

其他回答

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以一种更可读的同步方式来利用文件创建;但是,这超出了问题的范围。

解决方案

CommonJS

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

const dir = path.resolve(path.join(__dirname, 'upload');

if (!fs.existsSync(dir)) {
  fs.mkdirSync(dir);
}

// OR
if (!fs.existsSync(dir)) {
  fs.mkdirSync(dir, {
    mode: 0o744, // Not supported on Windows. Default: 0o777
  });
}

ESM

更新您的包。Json文件配置

{
  // declare using ECMAScript modules(ESM)
  "type": "module",
  //...
}
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

// create one custom `__dirname`, because it does not exist in es-module env ⚠️
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const dir = path.resolve(path.join(__dirname, 'upload');

if (!fs.existsSync(dir)) {
  fs.mkdirSync(dir);
}

// OR
if (!fs.existsSync(dir)) {
  fs.mkdirSync(dir, {
    mode: 0o744, // Not supported on Windows. Default: 0o777
  });
}

更新2022

import { existsSync } from 'node:fs';

refs

NodeJS版本:v18.2.0

https://nodejs.org/api/fs.html#fsexistssyncpath

https://nodejs.org/api/fs.html#fsmkdirsyncpath-options

https://nodejs.org/api/url.html#urlfileurltopathurl

https://github.com/nodejs/help/issues/2907#issuecomment-757446568

ESM: ECMAScript模块

https://nodejs.org/api/esm.html#introduction

使用Node.js 10 + ES6:

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

(async () => {
  const dir = path.join(__dirname, 'upload');

  try {
    await fs.promises.mkdir(dir);
  } catch (error) {
    if (error.code === 'EEXIST') {
      // Something already exists, but is it a file or directory?
      const lstat = await fs.promises.lstat(dir);

      if (!lstat.isDirectory()) {
        throw error;
      }
    } else {
      throw error;
    }
  }
})();

从文档中可以看出,这是你异步(和递归)做这件事的方式:

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

fsPromises.access(dir, fs.constants.F_OK)
   .catch(async() => {
                await fs.mkdir(dir, { recursive: true }, function(err) {
                    if (err) {
                      console.log(err)
                    }
                  })
    });

一行解决方案:如果目录不存在,则创建该目录

// import
const fs = require('fs')  // In JavaScript
import * as fs from "fs"  // in TypeScript
import fs from "fs"       // in Typescript

// Use
!fs.existsSync(`./assets/`) && fs.mkdirSync(`./assets/`, { recursive: true })