- Скрин из настроек
- Цвета для консоли
Код
const fs = require('fs')
const path = require('path')
const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
// Хэлпер для обработки ввода от пользователя в терминале
const askQuestion = query => {
return new Promise(resolve => rl.question(query, resolve))
}
// Функция для получения пути к директории компонента
const getComponentDir = (componentName) => path.join(process.cwd(), componentName)
// Функция для создания файла стилей
const createStylesFile = ({ componentDir, componentName }) => {
const content = `.root {}`
const filePath = path.join(componentDir, `${componentName}.module.scss`)
fs.writeFileSync(filePath, content)
}
// Функция для создания файла типов
const createTypesFile = ({ componentDir, componentName }) => {
const typesContent = `export interface ${componentName}Props {}`
const filePath = path.join(componentDir, `${componentName}.types.ts`)
fs.writeFileSync(filePath, typesContent)
}
// Функция для создания основного файла компонента
const createComponentFile = ({ componentDir, componentName, needStyle, needTypes }) => {
const componentContent = []
componentContent.push("import React from 'react'")
if (needStyle) {
componentContent.push(`import styles from './${componentName}.module.scss'`)
}
if (needTypes) {
componentContent.push(`import { ${componentName}Props } from './${componentName}.types.ts'`)
}
componentContent.push(``)
if (needTypes) {
componentContent.push(
`export const ${componentName} = (props: ${componentName}Props) => {`
)
} else {
componentContent.push(`export const ${componentName} = () => {`)
}
if (needStyle) {
componentContent.push(
` return <div className={styles.root}>${componentName}</div>`
)
} else {
componentContent.push(` return <div>${componentName}</div>`)
}
componentContent.push(`}`)
componentContent.push(``)
const filePath = path.join(componentDir, `${componentName}.tsx`)
fs.writeFileSync(
filePath,
componentContent.join('\\n')
)
}
// Основная функция для генерации компонента
const createIndexFile = ({ componentDir, componentName, needTypes }) => {
const componentContent = []
componentContent.push(`export { ${componentName} } from './${componentName}'`)
if (needTypes) {
componentContent.push(
`export type { ${componentName}Props } from './${componentName}.types.ts'`
)
}
componentContent.push(``)
const filePath = path.join(componentDir, 'index.ts')
fs.writeFileSync(
filePath,
componentContent.join('\\n')
)
}
// Основа
async function generateComponent() {
let componentName = await askQuestion('Component name? ')
// Валидация имени компонента
while (!componentName) {
console.error('Component name cannot be empty.')
componentName = await askQuestion('Component name? ')
}
const needStyle = await askQuestion('Need style file? (y/n) ').then(
res => res.toLowerCase() === 'y'
)
const needTypes = await askQuestion('Need types file? (y/n) ').then(
res => res.toLowerCase() === 'y'
)
const componentDir = getComponentDir(componentName)
// Валидация папки
if (fs.existsSync(componentDir)) {
throw new Error(
`A directory with the name "${componentName}" already exists.`
)
}
fs.mkdirSync(componentDir)
createComponentFile({
componentDir,
componentName,
needStyle,
needTypes
})
if (needStyle) {
createStylesFile({ componentDir, componentName })
}
if (needTypes) {
createTypesFile({ componentName, componentDir })
}
createIndexFile({ componentDir, componentName, needTypes })
console.log(
'\\x1b[32m%s\\x1b[0m',
`Component "${componentName}" created successfully.`
)
rl.close()
}
// Триггер, запускающий генерацию компонента
generateComponent().catch(err => {
console.error('An error occurred:', err)
rl.close()
})