leon9208
@leon9208
Начинающий web-developer

Как автоматически создавать пустые файлы внутри созданной папки?

Всем привет, начинаю знакомиться с Gulp + БЭМ.

Как сделать автоматическое создание пустых файлов и папок, при создании новых папок (блоков), названия файлов брать из названия папки (родителя).

blocks
  • header
    • header.sass
    • header.js
    • header.pug
    • img

  • footer
    • footer.sass
    • footer.js
    • footer.pug
    • img

  • reviews
    • reviews.sass
    • reviews.js
    • reviews.pug
    • img



Т.е. отслеживать созданные папки (блоки) и создавать автоматически внутри типовые файлы и папки.
Сейчас всё это делаю вручную, хотелось немного облегчить себе жизнь путем автоматизации.

P.S. Буду благодарен если кто поделиться своим опытом, кто как делает, может моё видение не совсем верно и нужно делать иначе.

Решение ниже:

const gulp = require('gulp');
const fs = require('fs');
const allBlocks = './src/blocks/'; // Путь до директории с блоками

// Отслеживаем добавление новых директорий
  gulp.watch(allBlocks).on('addDir', function() {
    const dirs = fs.readdirSync(allBlocks); // Получаем список дочерних директорий
   // Перебираем список с проверкой на наличие внутри директорий совпадений с файлами (.pug/.sass/.js), все эти файлы с названием блока(папки)
    for(i = 0; i < dirs.length;i++){
      if(fs.existsSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.pug') === false && fs.existsSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.sass') === false && fs.existsSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.js') === false){
        fs.appendFileSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.pug', ''); // Добавляем пустой файл с названием блока blockName.pug
        fs.appendFileSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.js', ''); // Добавляем пустой файл с названием блока blockName.js
        fs.appendFileSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.sass', ''); // Добавляем пустой файл с названием блока blockName.sass
      }
      try {
        fs.statSync(allBlocks+'/'+dirs[i]+'/img');
      }
      catch (err) {
        // Если в блоке нет директории img, то соответственно добавляем.
        if (err.code === 'ENOENT') {
          fs.mkdirSync(allBlocks+'/'+dirs[i]+'/img');
          console.log('Папка img добавлена в директорию' + ' — ' + dirs[i]);
        }
      }
    }
  });
  • Вопрос задан
  • 1028 просмотров
Решения вопроса 1
leon9208
@leon9208 Автор вопроса
Начинающий web-developer
const gulp = require('gulp');
const fs = require('fs');
const allBlocks = './src/blocks/'; // Путь до директории с блоками

// Отслеживаем добавление новых директорий
  gulp.watch(allBlocks).on('addDir', function() {
    const dirs = fs.readdirSync(allBlocks); // Получаем список дочерних директорий
   // Перебираем список с проверкой на наличие внутри директорий совпадений с файлами (.pug/.sass/.js), все эти файлы с названием блока(папки)
    for(i = 0; i < dirs.length;i++){
      if(fs.existsSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.pug') === false && fs.existsSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.sass') === false && fs.existsSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.js') === false){
        fs.appendFileSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.pug', ''); // Добавляем пустой файл с названием блока blockName.pug
        fs.appendFileSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.js', ''); // Добавляем пустой файл с названием блока blockName.js
        fs.appendFileSync(allBlocks+'/'+dirs[i]+'/'+dirs[i]+'.sass', ''); // Добавляем пустой файл с названием блока blockName.sass
      }
      try {
        fs.statSync(allBlocks+'/'+dirs[i]+'/img');
      }
      catch (err) {
        // Если в блоке нет директории img, то соответственно добавляем.
        if (err.code === 'ENOENT') {
          fs.mkdirSync(allBlocks+'/'+dirs[i]+'/img');
          console.log('Папка img добавлена в директорию' + ' — ' + dirs[i]);
        }
      }
    }
  });


P.S. Отдельное спасибо Сергей delphinpro за наводку, за ссылки на документацию (на нужный раздел) и на статьи по теме!
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
Adamos
@Adamos
#!/bin/bash
mkdir -p $1/img
exts=('sass' 'js' 'pug')
for ext in ${exts[@]}
do
touch $1/$(basename $1).$ext
done
Ответ написан
delphinpro
@delphinpro Куратор тега JavaScript
frontend developer
Всё верно, написать отдельный таск для галпа или скрипт для запуска через npm run

Скрипт простой: создать папку, создать файлы.
Полная документация по работе с файловой системой https://nodejs.org/api/fs.html
И небольшой конспект на хабре https://habr.com/ru/company/ruvds/blog/424969/ (этого должно хватить)
Ответ написан
@zverygi
Немного знаю html
отдельный скрипт для запуска через npm, код ниже создает папку и три файла .pug, .sass, .js. Все это дело ложим в корень в файл .js, ну и правим путь к общей папки где будут лежать модули в этой строке "const BLOCKS_DIR = path.join(__dirname, 'dev/pug/modules');"

// создание блока набрать node block you_block_name
'use strict';

const fs = require('fs')
const path = require('path')
const colors = require('colors')
const readline = require('readline')

const rl = readline.createInterface(process.stdin, process.stdout);

// folder with all blocks
const BLOCKS_DIR = path.join(__dirname, 'dev/pug/modules');

//////////////////////////////////////////////////////////////////////////////////////////////////

// default content for files in new block
const fileSources = {
	pug : `mixin {blockName}()\n\t.{blockName}\n\t\t| {blockName}\n`,
	sass: `/*! {blockName} style */ \n` //можно задать изначальные значения/текст
//	js	: `// .{blockName} scripts goes here`
};

function validateBlockName(blockName) {
	return new Promise((resolve, reject) => {
		const isValid = /^(\d|\w|-)+$/.test(blockName);

		if (isValid) {
			resolve(isValid);
		} else {
			const errMsg = (
				`ERR>>> An incorrect block name '${blockName}'\n` +
				`ERR>>> A block name must include letters, numbers & the minus symbol.`
			);
			reject(errMsg);
		}
	});
}

function directoryExist(blockPath, blockName) {
	return new Promise((resolve, reject) => {
		fs.stat(blockPath, notExist => {
			if (notExist) {
				resolve();
			} else {
				reject(`ERR>>> The block '${blockName}' already exists.`.red);
			}
		});
	});
}

function createDir(dirPath) {
	return new Promise((resolve, reject) => {
		fs.mkdir(dirPath, err => {
			if (err) {
				reject(`ERR>>> Failed to create a folder '${dirPath}'`.red);
			} else {
				resolve();
			}
		});
	});
}

function createFiles(blocksPath, blockName) {
	const promises = [];
	Object.keys(fileSources).forEach(ext => {
		const fileSource = fileSources[ext].replace(/\{blockName}/g, blockName);
		const filename = `${blockName}.${ext}`;
		const filePath = path.join(blocksPath, filename);

		promises.push(
				new Promise((resolve, reject) => {
					fs.writeFile(filePath, fileSource, 'utf8', err => {
						if (err) {
							reject(`ERR>>> Failed to create a file '${filePath}'`.red);
						} else {
							resolve();
						}
					});
				})
		);
	});

	return Promise.all(promises);
}

function getFiles(blockPath) {
	return new Promise((resolve, reject) => {
		fs.readdir(blockPath, (err, files) => {
			if (err) {
				reject(`ERR>>> Failed to get a file list from a folder '${blockPath}'`);
			} else {
				resolve(files);
			}
		});
	});
}

function printErrorMessage(errText) {
	console.log(errText);
	rl.close();
}

// //////////////////////////////////////////////////////////////////////////

function initMakeBlock(blockName) {
	const blockPath = path.join(BLOCKS_DIR, blockName);

	return validateBlockName(blockName)
		.then(() => directoryExist(blockPath, blockName))
		.then(() => createDir(blockPath))
		.then(() => createFiles(blockPath, blockName))
		.then(() => getFiles(blockPath))
		.then(files => {
			const line = '-'.repeat(48 + blockName.length);
			console.log(line);
			console.log(`The block has just been created in 'source/blocks/${blockName}'`);
			console.log(line);

			// Displays a list of files created
			files.forEach(file => console.log(file.yellow));

			rl.close();
		});
}


// //////////////////////////////////////////////////////////////////////////
//
// Start here
//

// Command line arguments
const blockNameFromCli = process.argv
		.slice(2)
		// join all arguments to one string (to simplify the capture user input errors)
		.join(' ');


// If the user pass the name of the block in the command-line options
// that create a block. Otherwise - activates interactive mode
if (blockNameFromCli !== '') {
	initMakeBlock(blockNameFromCli).catch(printErrorMessage);
}
else {
	rl.setPrompt('Block name: '.magenta);
	rl.prompt();
	rl.on('line', (line) => {
		const blockName = line.trim();
		initMakeBlock(blockName).catch(printErrorMessage);
	});
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы