Skip to content

Instantly share code, notes, and snippets.

@leventebalogh
Last active May 25, 2017 11:50
Show Gist options
  • Save leventebalogh/6dc217717f949c343cc4e1496f6824c6 to your computer and use it in GitHub Desktop.
Save leventebalogh/6dc217717f949c343cc4e1496f6824c6 to your computer and use it in GitHub Desktop.
A script for generating React Components
#! /usr/bin/env node
/**
* Usage:
* 1. "$ chmod +x ./generate-component" ==> make it executable
* 2. "$ cp ./generate-component ~/bin/generate-component && export PATH=~/bin:$PATH" ==> add it to the PATH
* 3. "$ generate component <component-name> <target-path>" ==> run it
*
* Component Layout:
*
* <component-name>/
* +- <component-name>.jsx
* +- <component-name>.css
* +- index.js
*
* Examples:
* - "$ generate-component Foo" -> generates component in folder "./Foo"
* - "$ generate-component Foo ./components" -> generates component in folder "./components/Foo"
*/
const fs = require('fs');
const path = require('path');
const cwd = process.cwd();
const COMPONENT_NAME = process.argv[2] || '';
const COMPONENT_PATH = process.argv[3] ? path.resolve(process.argv[3]) : cwd;
const COMPONENT_DIR = path.join(COMPONENT_PATH, capitalize(COMPONENT_NAME));
const FILE_TEMPLATES = {
'index.js': `export { default } from './{{ componentName }}';`,
'{{ componentName }}.jsx': getComponentTemplate(),
'{{ componentName }}.css': `.{{ smallCapsComponentName }} {}`
};
checkUsage();
log('Generating component...');
createDirectory();
createFiles(FILE_TEMPLATES);
log('Component generated successfully.');
function checkUsage () {
if (!COMPONENT_NAME) {
log('WRONG_USAGE\n');
log('Usage: $ generate-component <component-name> <path>')
process.exit(1);
}
if (fs.existsSync(COMPONENT_DIR)) {
log('ALREADY_EXISTS\n');
log(`Component "${ capitalize(COMPONENT_NAME) }" already exists at "${ COMPONENT_PATH }"`);
process.exit(1);
}
}
function log (message) {
console.log(message);
}
function createDirectory () {
fs.mkdirSync(COMPONENT_DIR);
}
function createFiles (templates) {
Object.keys(templates).forEach(filename => createFile(filename, templates[filename]));
}
function createFile (filename, template) {
const compiledFilename = filename.replace(/{{ componentName }}/gmi, capitalize(COMPONENT_NAME));
const filePath = path.join(COMPONENT_DIR, compiledFilename);
template = template.replace(/{{ componentName }}/gmi, capitalize(COMPONENT_NAME));
template = template.replace(/{{ smallCapsComponentName }}/gmi, COMPONENT_NAME.toLowerCase());
fs.writeFileSync(filePath, template, 'utf8');
}
function getComponentTemplate () {
return `import React from 'react';
import styles from './{{ componentName }}.css';
export default function {{ componentName }} () {
return (
<div className={ styles.{{ smallCapsComponentName }} }></div>
);
}`;
}
function capitalize (string) {
return `${ string.charAt(0).toUpperCase() }${ string.slice(1) }`;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment