Last active
May 12, 2022 19:37
-
-
Save qramilq/b4357b5f278f07b633ba0ecade910db0 to your computer and use it in GitHub Desktop.
Generating React component's files from command line
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { component, types, barrel } = require('./templates.js'); | |
exports.DEFAULT_COMPONENT_BASE_PATH = './common/components'; | |
exports.FILES_DATA = [ | |
{ | |
getPath: ({ componentName, componentPath }) => `${componentPath}/${componentName}.tsx`, // [component].tsx | |
getTemplate: component, | |
}, | |
{ | |
getPath: ({ componentName, componentPath }) => `${componentPath}/${componentName}.types.ts`, // [component].types.ts | |
getTemplate: types, | |
}, | |
{ | |
getPath: ({ componentPath }) => `${componentPath}/index.ts`, // index.ts | |
getTemplate: barrel, | |
}, | |
{ | |
getPath: ({ componentName, componentPath }) => `${componentPath}/${componentName}.module.css`, | |
getTemplate: () => '', | |
}, | |
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs'); | |
const rl = require('./readline'); | |
const { | |
promptNGetComponentName, | |
promptNGetComponentPath, | |
createComponentFiles, | |
} = require('./helpers'); | |
async function start() { | |
const componentName = await promptNGetComponentName(); | |
const componentPath = await promptNGetComponentPath(componentName); | |
if (fs.existsSync(componentPath)) { | |
throw new Error('A component with that name already exists.'); | |
} | |
fs.mkdirSync(componentPath); | |
await createComponentFiles(componentPath, componentName); | |
rl.close(); | |
} | |
start(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs'); | |
const rl = require('./readline'); | |
const { FILES_DATA, DEFAULT_COMPONENT_BASE_PATH } = require('./constants'); | |
/** | |
* | |
* @returns {Promise<string>} | |
*/ | |
async function promptNGetComponentName() { | |
const rawComponentName = await rl.getInputData(`Enter component's name:`); | |
const componentNameWithCapitalizedFirstLetter = | |
rawComponentName.charAt(0).toUpperCase() + rawComponentName.slice(1); | |
return componentNameWithCapitalizedFirstLetter; | |
} | |
/** | |
* | |
* @param {string} componentName - Component's name will include in path | |
* @returns {Promise<string>} | |
*/ | |
async function promptNGetComponentPath(componentName) { | |
const defaultComponentPath = `${DEFAULT_COMPONENT_BASE_PATH}/${componentName}`; | |
const rawCoponentPath = await rl.getInputData( | |
`Enter component's path [${defaultComponentPath}]: `, | |
); | |
return rawCoponentPath || defaultComponentPath; | |
} | |
/** | |
* | |
* @param {string} componentPath | |
* @param {string} componentName | |
* @returns {Promise<void[]>} | |
*/ | |
async function createComponentFiles(componentPath, componentName) { | |
const writeFileErrorHandler = (err) => { | |
if (err) throw err; | |
}; | |
return Promise.all( | |
FILES_DATA.map(({ getPath, getTemplate }) => | |
fs.writeFile( | |
getPath({ componentPath, componentName }), | |
getTemplate(componentName), | |
writeFileErrorHandler, | |
), | |
), | |
); | |
} | |
module.exports = { | |
promptNGetComponentName, | |
promptNGetComponentPath, | |
createComponentFiles, | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const readline = require('readline'); | |
/** | |
* Readline wrapper | |
* @class | |
*/ | |
class ReadLine { | |
#rl; | |
static instance; | |
constructor() { | |
this.#rl = readline.createInterface({ | |
input: process.stdin, | |
output: process.stdout, | |
}); | |
} | |
/** | |
* | |
* @param {string} question | |
* @returns {Promise<string>} | |
*/ | |
getInputData(question) { | |
return new Promise((resolve) => this.#rl.question(question, resolve)); | |
} | |
/** | |
* See {@link readline.Interface.close close() property}. | |
*/ | |
close() { | |
this.#rl.close(); | |
} | |
} | |
module.exports = new ReadLine(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
exports.component = (name) => `import { ${name}Props } from './${name}.types'; | |
import styles from './${name}.module.css'; | |
export function ${name}(props: ${name}Props) { | |
return <div>${name}Component</div>; | |
} | |
`; | |
exports.types = (name) => `export interface ${name}Props {} | |
`; | |
exports.barrel = (name) => `export * from './${name}'; | |
`; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment