new-component
Advanced tools
Comparing version 1.0.1 to 2.0.0
{ | ||
"name": "new-component", | ||
"version": "1.0.1", | ||
"version": "2.0.0", | ||
"description": "CLI for creating new React components", | ||
"homepage": "https://github.com/joshwcomeau/new-component", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/joshwcomeau/new-component" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/joshwcomeau/new-component/issues" | ||
}, | ||
"main": "src/index.js", | ||
@@ -13,3 +21,4 @@ "scripts": { | ||
"cli", | ||
"component" | ||
"component", | ||
"boilerplate" | ||
], | ||
@@ -22,6 +31,6 @@ "author": "Joshua Comeau", | ||
"dependencies": { | ||
"chalk": "2.0.1", | ||
"commander": "2.11.0", | ||
"chalk": "^2.4.1", | ||
"commander": "^2.15.1", | ||
"prettier": "1.5.3" | ||
} | ||
} |
@@ -8,2 +8,3 @@ <p align="center"> | ||
# `new-component` | ||
### Simple, customizable utility for adding new React components to your project. | ||
@@ -20,2 +21,3 @@ | ||
## Features | ||
- Simple CLI interface for adding Component, PureComponent, or Stateless Functional components. | ||
@@ -26,3 +28,2 @@ - Uses [Prettier](https://github.com/prettier/prettier) to stylistically match the existing project. | ||
<br /> | ||
@@ -35,2 +36,6 @@ | ||
```bash | ||
# Using Yarn: | ||
$ yarn global add new-component | ||
# or, using NPM | ||
$ npm i -g new-component | ||
@@ -69,3 +74,2 @@ ``` | ||
<br /> | ||
@@ -83,4 +87,2 @@ | ||
<br /> | ||
@@ -93,7 +95,8 @@ | ||
Control the type of component created: | ||
- `class` for a traditional Component class (default), | ||
- `functional` for a stateless functional component (default). | ||
- `class` for a traditional Component class, | ||
- `pure-class` for a PureComponent class, | ||
- `functional` for a stateless functional component. | ||
Legacy `createClass` components are not supported, although support would be easy to add. Feel free to open an issue (or a PR!). | ||
Legacy `createClass` components are not supported. | ||
@@ -111,4 +114,2 @@ **Usage:** | ||
Legacy `createClass` components are not supported, although support would be easy to add. Feel free to open an issue (or a PR!). | ||
**Usage:** | ||
@@ -151,19 +152,24 @@ | ||
"singleQuote": true, | ||
"semi": false | ||
"semi": false, | ||
} | ||
} | ||
``` | ||
(Ideally, the plugin would consume your project's prettier settings automatically! But I haven't built this yet. PRs welcome!) | ||
<br /> | ||
## Platform Support | ||
This has only been tested in MacOS. I think it'd work fine in linux, but I haven't tested it. Windows is a big question mark (would welcome contribution here!). | ||
This has only been tested in macOS. I think it'd work fine in linux, but I haven't tested it. Windows is a big question mark (would welcome contribution here!). | ||
<br /> | ||
## TODO | ||
## Development | ||
This is a brand new thing! I'd like to add more functionality: | ||
To get started with development: | ||
- Built-in support for common style tools (CSS modules, Aphrodite, styled-components, etc). | ||
- Better error messaging, more edge-case support | ||
- Editor integrations :o | ||
- Check out this git repo locally, you will need to ensure you have Yarn installed globally. | ||
- In the folder run `yarn install` | ||
- Check that command runs `node ../new-component/src/index.js --help` | ||
- Alternatively you can set up a symlink override by running `npm link` then `new-component --help`. Note: this will override any globally installed version of this package. |
@@ -17,23 +17,2 @@ /* | ||
const colors = { | ||
red: [216, 16, 16], | ||
green: [142, 215, 0], | ||
blue: [0, 186, 255], | ||
gold: [255, 204, 0], | ||
mediumGray: [128, 128, 128], | ||
darkGray: [90, 90, 90], | ||
}; | ||
const logComponentType = (selected) => ( | ||
['class', 'pure-class', 'functional'] | ||
.sort((a, b) => a === selected ? -1 : 1) | ||
.map(option => ( | ||
option === selected | ||
? `${chalk.bold.rgb(...colors.blue)(option)}` | ||
: `${chalk.rgb(...colors.darkGray)(option)}` | ||
)).join(' ') | ||
); | ||
// Get the configuration for this component. | ||
@@ -53,24 +32,48 @@ // Overrides are as follows: | ||
const defaults = { | ||
type: 'class', | ||
type: 'functional', | ||
dir: 'src/components', | ||
extension: 'js' | ||
extension: 'js', | ||
}; | ||
const globalOverrides = requireOptional(`/${home}/.new-component-config.json`); | ||
const globalOverrides = requireOptional( | ||
`/${home}/.new-component-config.json` | ||
); | ||
const localOverrides = requireOptional(`/${currentPath}/.new-component-config.json`); | ||
const localOverrides = requireOptional( | ||
`/${currentPath}/.new-component-config.json` | ||
); | ||
return Object.assign({}, defaults, globalOverrides, localOverrides); | ||
} | ||
return Object.assign({}, globalOverrides, localOverrides, defaults); | ||
}; | ||
module.exports.buildPrettifier = prettierConfig => text => ( | ||
prettier.format(text, prettierConfig) | ||
); | ||
module.exports.buildPrettifier = (prettierConfig) => (text) => | ||
prettier.format(text, prettierConfig); | ||
// Emit a message confirming the creation of the component | ||
const colors = { | ||
red: [216, 16, 16], | ||
green: [142, 215, 0], | ||
blue: [0, 186, 255], | ||
gold: [255, 204, 0], | ||
mediumGray: [128, 128, 128], | ||
darkGray: [90, 90, 90], | ||
}; | ||
const logComponentType = (selected) => | ||
['class', 'pure-class', 'functional'] | ||
.sort((a, b) => (a === selected ? -1 : 1)) | ||
.map((option) => | ||
option === selected | ||
? `${chalk.bold.rgb(...colors.blue)(option)}` | ||
: `${chalk.rgb(...colors.darkGray)(option)}` | ||
) | ||
.join(' '); | ||
module.exports.logIntro = ({ name, dir, type }) => { | ||
console.info('\n'); | ||
console.info(`✨ Creating the ${chalk.bold.rgb(...colors.gold)(name)} component ✨`); | ||
console.info( | ||
`✨ Creating the ${chalk.bold.rgb(...colors.gold)(name)} component ✨` | ||
); | ||
console.info('\n'); | ||
const pathString = chalk.bold.rgb(...colors.blue)(dir); | ||
@@ -81,3 +84,5 @@ const typeString = logComponentType(type); | ||
console.info(`Type: ${typeString}`); | ||
console.info(chalk.rgb(...colors.darkGray)('=========================================')); | ||
console.info( | ||
chalk.rgb(...colors.darkGray)('=========================================') | ||
); | ||
@@ -90,3 +95,3 @@ console.info('\n'); | ||
console.info(`${checkmark} ${successText}`); | ||
} | ||
}; | ||
@@ -96,5 +101,7 @@ module.exports.logConclusion = () => { | ||
console.info(chalk.bold.rgb(...colors.green)('Component created! 🚀 ')); | ||
console.info(chalk.rgb(...colors.mediumGray)('Thanks for using new-component.')); | ||
console.info( | ||
chalk.rgb(...colors.mediumGray)('Thanks for using new-component.') | ||
); | ||
console.info('\n'); | ||
} | ||
}; | ||
@@ -106,2 +113,2 @@ module.exports.logError = (error) => { | ||
console.info('\n'); | ||
} | ||
}; |
@@ -22,3 +22,2 @@ #!/usr/bin/env node | ||
// Load our package.json, so that we can pass the version onto `commander`. | ||
@@ -35,3 +34,2 @@ const { version } = require('../package.json'); | ||
program | ||
@@ -42,14 +40,17 @@ .version(version) | ||
'-t, --type <componentType>', | ||
'Type of React component to generate (default: "class")', | ||
'Type of React component to generate (default: "functional")', | ||
/^(class|pure-class|functional)$/i, | ||
config.type | ||
).option( | ||
) | ||
.option( | ||
'-d, --dir <pathToDirectory>', | ||
'Path to the "components" directory (default: "src/components")', | ||
config.dir | ||
).option( | ||
) | ||
.option( | ||
'-x, --extension <fileExtension>', | ||
'Which file extension to use for the component (default: "js")', | ||
config.extension | ||
).parse(process.argv); | ||
) | ||
.parse(process.argv); | ||
@@ -73,2 +74,9 @@ const [componentName] = program.args; | ||
// Check if componentName is provided | ||
if (!componentName) { | ||
logError( | ||
`Sorry, you need to specify a name for your component like this: new-component <name>` | ||
); | ||
process.exit(0); | ||
} | ||
@@ -78,3 +86,5 @@ // Check to see if a directory at the given path exists | ||
if (!fs.existsSync(fullPathToParentDir)) { | ||
logError(`Sorry, you need to create a parent "components" directory.\n(new-component is looking for a directory at ${program.dir}).`) | ||
logError( | ||
`Sorry, you need to create a parent "components" directory.\n(new-component is looking for a directory at ${program.dir}).` | ||
); | ||
process.exit(0); | ||
@@ -86,3 +96,5 @@ } | ||
if (fs.existsSync(fullPathToComponentDir)) { | ||
logError(`Looks like this component already exists! There's already a component at ${componentDir}.\nPlease delete this directory and try again.`) | ||
logError( | ||
`Looks like this component already exists! There's already a component at ${componentDir}.\nPlease delete this directory and try again.` | ||
); | ||
process.exit(0); | ||
@@ -93,34 +105,32 @@ } | ||
mkDirPromise(componentDir) | ||
.then(() => ( | ||
readFilePromiseRelative(templatePath) | ||
)) | ||
.then(template => { | ||
.then(() => readFilePromiseRelative(templatePath)) | ||
.then((template) => { | ||
logItemCompletion('Directory created.'); | ||
return template; | ||
}) | ||
.then(template => ( | ||
.then((template) => | ||
// Replace our placeholders with real data (so far, just the component name) | ||
template.replace(/COMPONENT_NAME/g, componentName) | ||
)) | ||
.then(template => ( | ||
) | ||
.then((template) => | ||
// Format it using prettier, to ensure style consistency, and write to file. | ||
writeFilePromise(filePath, prettify(template)) | ||
)) | ||
.then(template => { | ||
) | ||
.then((template) => { | ||
logItemCompletion('Component built and saved to disk.'); | ||
return template; | ||
}) | ||
.then(template => ( | ||
.then((template) => | ||
// We also need the `index.js` file, which allows easy importing. | ||
writeFilePromise(indexPath, prettify(indexTemplate)) | ||
)) | ||
.then(template => { | ||
) | ||
.then((template) => { | ||
logItemCompletion('Index file built and saved to disk.'); | ||
return template; | ||
}) | ||
.then(template => { | ||
.then((template) => { | ||
logConclusion(); | ||
}) | ||
.catch(err => { | ||
.catch((err) => { | ||
console.error(err); | ||
}) | ||
}); |
@@ -15,3 +15,2 @@ /* | ||
module.exports.requireOptional = (filePath) => { | ||
@@ -30,3 +29,3 @@ try { | ||
module.exports.mkDirPromise = (dirPath) => ( | ||
module.exports.mkDirPromise = (dirPath) => | ||
new Promise((resolve, reject) => { | ||
@@ -36,8 +35,7 @@ fs.mkdir(dirPath, (err) => { | ||
}); | ||
}) | ||
); | ||
}); | ||
// Simple promise wrappers for read/write files. | ||
// utf-8 is assumed. | ||
module.exports.readFilePromise = fileLocation => ( | ||
module.exports.readFilePromise = (fileLocation) => | ||
new Promise((resolve, reject) => { | ||
@@ -47,6 +45,5 @@ fs.readFile(fileLocation, 'utf-8', (err, text) => { | ||
}); | ||
}) | ||
); | ||
}); | ||
module.exports.writeFilePromise = (fileLocation, fileContent) => ( | ||
module.exports.writeFilePromise = (fileLocation, fileContent) => | ||
new Promise((resolve, reject) => { | ||
@@ -56,4 +53,3 @@ fs.writeFile(fileLocation, fileContent, 'utf-8', (err) => { | ||
}); | ||
}) | ||
); | ||
}); | ||
@@ -64,4 +60,3 @@ // Somewhat counter-intuitively, `fs.readFile` works relative to the current | ||
// to the code's directory. | ||
module.exports.readFilePromiseRelative = fileLocation => ( | ||
module.exports.readFilePromise(path.join(__dirname, fileLocation)) | ||
); | ||
module.exports.readFilePromiseRelative = (fileLocation) => | ||
module.exports.readFilePromise(path.join(__dirname, fileLocation)); |
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
271
0
1
167
3
85003
12
+ Addedchalk@2.4.2(transitive)
+ Addedcommander@2.20.3(transitive)
+ Addedhas-flag@3.0.0(transitive)
+ Addedsupports-color@5.5.0(transitive)
- Removedchalk@2.0.1(transitive)
- Removedcommander@2.11.0(transitive)
- Removedhas-flag@2.0.0(transitive)
- Removedsupports-color@4.5.0(transitive)
Updatedchalk@^2.4.1
Updatedcommander@^2.15.1