-
-
Save drodsou/de2ba6291aea67ffc5bc4b52d8c32abd to your computer and use it in GitHub Desktop.
| // -- updated in 2020/04/19 covering the issues in the comments to this point | |
| // -- remember you also have things like `ensureDirSync` from https://github.com/jprichardson/node-fs-extra/blob/master/docs/ensureDir-sync.md | |
| const fs = require('fs') | |
| function writeFileSyncRecursive(filename, content, charset) { | |
| // -- normalize path separator to '/' instead of path.sep, | |
| // -- as / works in node for Windows as well, and mixed \\ and / can appear in the path | |
| let filepath = filename.replace(/\\/g,'/'); | |
| // -- preparation to allow absolute paths as well | |
| let root = ''; | |
| if (filepath[0] === '/') { | |
| root = '/'; | |
| filepath = filepath.slice(1); | |
| } | |
| else if (filepath[1] === ':') { | |
| root = filepath.slice(0,3); // c:\ | |
| filepath = filepath.slice(3); | |
| } | |
| // -- create folders all the way down | |
| const folders = filepath.split('/').slice(0, -1); // remove last item, file | |
| folders.reduce( | |
| (acc, folder) => { | |
| const folderPath = acc + folder + '/'; | |
| if (!fs.existsSync(folderPath)) { | |
| fs.mkdirSync(folderPath); | |
| } | |
| return folderPath | |
| }, | |
| root // first 'acc', important | |
| ); | |
| // -- write file | |
| fs.writeFileSync(root + filepath, content, charset); | |
| } | |
| // -- Tests done that work properly: | |
| // -- both in WSL and CMD | |
| // writeFileSyncRecursive('data.json', '{}', 'utf8'); | |
| // writeFileSyncRecursive('public/new-user/data.json', '{}', 'utf8'); | |
| // writeFileSyncRecursive('public\\new-user\\data.json', '{}', 'utf8'); | |
| // writeFileSyncRecursive('./public/new-user/data.json', '{}', 'utf8'); | |
| // writeFileSyncRecursive('.\\public\\new-user\\data.json', '{}', 'utf8'); | |
| // writeFileSyncRecursive('/tmp/public\\new-user\\data.json', '{}', 'utf8'); | |
| // -- only in WSL (in CMD creates a 'C:\c' folder) | |
| // writeFileSyncRecursive('/c/tmp/writefilesync/public/new-user/data.json', '{}', 'utf8'); | |
| // -- only in CMD (in WSL throws error no such file or directory c:/tmp) | |
| // writeFileSyncRecursive('c:\\tmp\\writefilesync\\public\\new-user\\data.json', '{}', 'utf8'); | |
| // writeFileSyncRecursive('c:/tmp/writefilesync/public/new-user/data.json', '{}', 'utf8'); | |
| /* | |
| // former implementation that received comments until 2020/04/19 | |
| // fixed missing second parameter in reduce (irkreja comment) | |
| // works well only with relative paths | |
| // asumes paths passed with / separator even in windows | |
| function writeFileSyncRecursive (filename, content, charset) { | |
| // create folder path if not exists | |
| filename.split('/').slice(0,-1).reduce( (last, folder)=>{ | |
| let folderPath = last ? (last + '/' + folder) : folder | |
| if (!fs.existsSync(folderPath)) fs.mkdirSync(folderPath) | |
| return folderPath | |
| },''); // fixed missing second parameter of reduce | |
| fs.writeFileSync(filename, content, charset) | |
| } | |
| */ |
something simpler could be
function writeFileSyncRecursive(filename, content = '') { fs.mkdirSync(path.dirname(filename), {recursive: true}) fs.writeFileSync(filename, content) }
this will create the file name as folder, for example if the filename variable is "c:/users/someone/folder/config.js", config.js will be created as folder, but I agree we can start something from mkdir
path.dirname strips the file name off of the path before creating the folders. The function works as intended.
ex.
// This returns "c:/users/someone/folder"
path.dirname("c:/users/someone/folder/config.js")something simpler could be
function writeFileSyncRecursive(filename, content = '') { fs.mkdirSync(path.dirname(filename), {recursive: true}) fs.writeFileSync(filename, content) }this will create the file name as folder, for example if the filename variable is "c:/users/someone/folder/config.js", config.js will be created as folder, but I agree we can start something from mkdir
path.dirnamestrips the file name off of the path before creating the folders. The function works as intended.ex.
// This returns "c:/users/someone/folder" path.dirname("c:/users/someone/folder/config.js")
This is the the only one that works cross platform, and the bonus is it's the smallest in terms of lines of code too 👍💯
this will create the file name as folder, for example if the filename variable is "c:/users/someone/folder/config.js", config.js will be created as folder, but I agree we can start something from mkdir