You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

generate-react-cli

Package Overview
Dependencies
Maintainers
1
Versions
88
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

generate-react-cli - npm Package Compare versions

Comparing version

to
2.0.0

CHANGELOG.md

108

package.json
{
"name": "generate-react-cli",
"version": "1.7.5",
"version": "2.0.0",
"description": "A simple React CLI to generate components instantly and more.",
"main": "src/index.js",
"repository": "https://github.com/arminbro/generate-react-cli",
"bugs": "https://github.com/arminbro/generate-react-cli/issues",
"author": "Armin Broubakarian",
"license": "MIT",
"main": "bin/generate-react",
"bin": {

@@ -10,8 +14,12 @@ "generate-react": "bin/generate-react",

},
"files": [
"bin/",
"src/",
"README.md",
"CHANGELOG.md",
"LICENSE"
],
"publishConfig": {
"access": "public"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [

@@ -23,4 +31,18 @@ "cli",

],
"author": "Armin Broubakarian",
"license": "MIT",
"engines": {
"node": ">=8.x",
"npm": ">= 5.x"
},
"browserslist": [
"maintained node versions"
],
"scripts": {
"cm": "npx git-cz",
"prebuild": "rimraf dist",
"build": "babel src --out-dir dist --ignore 'src/**/*.test.js'",
"build:watch": "npm run build -- --watch",
"test": "jest --coverage",
"test:watch": "npm run test -- --watch",
"release": "standard-version"
},
"dependencies": {

@@ -30,17 +52,69 @@ "chalk": "^3.0.0",

"deep-keys": "^0.5.0",
"esm": "^3.2.25",
"fs-extra": "^8.1.0",
"inquirer": "^7.0.0",
"lodash-es": "^4.17.15",
"lodash": "^4.17.15",
"replace": "^1.1.1"
},
"files": [
"bin/",
"src/",
"templates/"
],
"repository": {
"type": "git",
"url": "https://github.com/arminbro/generate-react-cli"
"devDependencies": {
"@babel/cli": "^7.7.5",
"@babel/core": "^7.7.5",
"@babel/preset-env": "^7.7.6",
"@commitlint/cli": "^8.2.0",
"@commitlint/config-conventional": "^8.2.0",
"babel-eslint": "^10.0.3",
"eslint": "^6.7.2",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-config-prettier": "^6.7.0",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.1",
"husky": "^3.1.0",
"jest": "^24.9.0",
"prettier": "^1.19.1",
"pretty-quick": "^2.0.1",
"rimraf": "^3.0.0",
"standard-version": "^7.0.1"
},
"babel": {
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": true
}
}
]
]
},
"jest": {
"testEnvironment": "node",
"collectCoverageFrom": [
"src/**/*.js"
],
"coverageThreshold": {
"global": {
"branches": 0,
"functions": 0,
"lines": 0,
"statements": 0
}
}
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
}

103

readme.md
# Generate React CLI
[![dependencies](https://david-dm.org/arminbro/generate-react-cli.svg)](https://david-dm.org/arminbro/generate-react-cli)
[![License](https://img.shields.io/npm/l/express.svg)](https://github.com/arminbro/generate-react-cli/blob/master/LICENSE)
<p align="center"><img src="src/assets/component-cmd.gif?raw=true"/></p>
<p align="center"><img src="docs/assets/component-cmd.gif?raw=true"/></p>
## Why?
To help speed up productivity in React projects and stop copying, pasting, and renaming files each time you want to create a new component.
**_Few notes:_**
- The CLI now supports two testing component library templates [Enzyme](https://airbnb.io/enzyme) & [Testing Library](https://testing-library.com) that work with [Jest](https://jestjs.io/).
- The CLI has an opinion on how files are structured within the project. We follow "[grouping by features](https://reactjs.org/docs/faq-structure.html#grouping-by-features-or-routes)."
[Create React App](https://create-react-app.dev/) and [Gatsby](https://www.gatsbyjs.org/) do a great job of initializing new projects, setting up the development environment, and optimizing the app for production use. Still, they don't have a way to generate new components similar to what [Angular CLI](https://cli.angular.io/) offers, and that's because they both try to stay as non-opinionated as possible and allow the developer to make those decisions. One example would be grouping by features vs. grouping by file type when creating components.
## Install
`npm i -g generate-react-cli`
Generate React CLI focuses on generating new components by running a simple command. It also doesn't care if you run it in an existing [CRA](https://create-react-app.dev/), [Gatsby](https://www.gatsbyjs.org/), or a custom React project you built on your own.
## Usage
It does, however, have an opinion on how component files are structured. It follows [grouping by feature](https://reactjs.org/docs/faq-structure.html#grouping-by-file-type) because we believe when you look at a component, you should see all of its corresponding files (i.e., stylesheet, test, and component) under one folder with the component name. We feel this approach provides a better developer experience.
### Generate Component
`generate-react component <ComponentName>`
**_A few notes:_**
#### Shorthand
`g-r c <ComponentName>`
- Now supports React TypeScript projects.
- Supports two different component testing libraries - [Testing Library](https://testing-library.com) and [Enzyme](https://airbnb.io/enzyme) - that work with [Jest](https://jestjs.io/). We assume that you have these libraries already configured in your React project.
This command will create a folder with your component name within your default (e.g. **src/components**) directory, and its corresponding files.
## You can install it globally and run it like this using npm:
#### Options
|Parameter|Description|Default Value|
|---------|-----------|-------|
| **-p** or<br>**--path** | Value of the path where you want the component to be generated in (e.g. **src/pages**). | **src/components**
| **-t** or<br>**--withTest** | Create a corresponding test file with this component? | **Boolean value selected in "generate-react-cli.json" config file**
| **-s** or<br>**--withStory** | Create a corresponding story file with this component? | **Boolean value selected in "generate-react-cli.json" config file**
| **-l** or<br>**--withLazy** | Create a corresponding lazy file (a file that lazy-loads your component out of the box and enables [code splitting](https://reactjs.org/docs/code-splitting.html#code-splitting)) with this component? | **Boolean value selected in "generate-react-cli.json" config file**
```
npm i -g generate-react-cli
generate-react component Box
```
## Or you can just run it using npx like this:
```
npx generate-react-cli component Box
```
_([npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) is a package runner tool that comes with npm 5.2+ and higher)_
## Config File
When you run generate-react-cli within your project the first time, it will ask you a series of questions to customize the cli for your project needs (this will create a "generate-react-cli.json" config file).
### e.g. **generate-react-cli.json**
```json

@@ -44,4 +49,5 @@ {

"css": {
"preprocessor": "scss",
"module": true
"preprocessor": "css",
"module": false,
"withStyle": true
},

@@ -52,8 +58,59 @@ "test": {

},
"withStory": true,
"withStory": false,
"withLazy": false
}
},
"usesTypeScript": false
}
```
## Usage
### Generate Component
```
npx generate-react-cli component Box
```
This command will create a folder with your component name within your default (e.g. **src/components**) directory, and its corresponding files.
#### **Example of the component files structure**
```
|-- /src
|-- /components
|-- /Box
|-- Box.js
|-- Box.css
|-- Box.test.js
```
#### Options
You can also override the generate-react-cli default config options for one-off commands. So for example, let's say in one of your projects you have set **withTest** to be `true` in your generate-react-cli config file as your default. You can override it for that one-off command like this:
```
npx generate-react-cli c Box --no-withTest
```
Or vice versa, if you have set **withTest** to be `false` you can do this:
```
npx generate-react-cli c Box --withTest
```
Otherwise, if you don't pass any options, it will just use the default ones from the generate-react-cli config file you have set.
| Parameter | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **--path** | Value of the path where you want the component to be generated in (e.g. **src/pages**). |
| **--withStyle** | Creates a corresponding stylesheet file with this component. |
| **--no-withStyle** | Creates component without the stylesheet file. |
| **--withTest** | Creates a corresponding test file with this component. |
| **--no-withTest** | Creates a component without the test file. |
| **--withStory** | Creates a corresponding story file with this component. |
| **--no-withStory** | Creates component without the story file. |
| **--withLazy** | Creates a corresponding lazy file (a file that lazy-loads your component out of the box and enables [code splitting](https://reactjs.org/docs/code-splitting.html#code-splitting)) with this component. |
| **--no-withLazy** | Creates a component without the lazy file. |
<br>
Have fun!

@@ -1,14 +0,14 @@

import chalk from 'chalk';
import { generateComponentTemplates, getTestingLibraryTemplate } from '../services/templateService';
import componentJsTemplate from '../templates/components/componentJsTemplate';
import componentLazyTemplate from '../templates/components/componentLazyTemplate';
import componentCssTemplate from '../templates/components/componentCssTemplate';
import componentStoryTemplate from '../templates/components/componentStoryTemplate';
const chalk = require('chalk');
const {
componentTemplateTypes,
generateComponentTemplates,
getComponentTemplate,
} = require('../services/componentTemplateService');
export function generateComponent(componentName, cmd, componentConfig) {
const componentPathDir = `${cmd.path}/${componentName}`;
const module = componentConfig.css.module ? '.module' : '';
let jsTemplate = componentJsTemplate;
function generateComponent(cmd, cliConfigFile, componentName) {
const componentTemplates = [];
const componentTemplateTypeList = Object.values(componentTemplateTypes);
// Make sure component name is valid.
// --- Make sure component name is valid.
if (!componentName.match(/^[$A-Z_][0-9A-Z_$]*$/i)) {

@@ -24,67 +24,23 @@ console.error(

// if test library is not Testing Library. Remove data-testid from jsTemplate
if (componentConfig.test.library !== 'Testing Library') {
jsTemplate = jsTemplate.replace(` data-testid="TemplateName"`, '');
}
// --- Iterate through componentTemplateTypeList and build a list of componentTemplates.
// if the css module is true make sure to update the componentJsTemplate accordingly
if (module.length) {
jsTemplate = jsTemplate.replace(
`'./TemplateName.module.css'`,
`'./${componentName}${module}.${componentConfig.css.preprocessor}'`
);
} else {
jsTemplate = jsTemplate.replace(`{styles.TemplateName}`, `"${componentName}"`);
jsTemplate = jsTemplate.replace(
`styles from './TemplateName.module.css'`,
`'./${componentName}${module}.${componentConfig.css.preprocessor}'`
);
}
for (let i = 0; i < componentTemplateTypeList.length; i += 1) {
const componentTemplateType = componentTemplateTypeList[i];
const componentTemplates = [
{
template: jsTemplate,
templateType: `Component "${componentName}.js"`,
componentPath: `${componentPathDir}/${componentName}.js`,
componentName,
},
{
template: componentCssTemplate,
templateType: `Stylesheet "${componentName}${module}.${componentConfig.css.preprocessor}"`,
componentPath: `${componentPathDir}/${componentName}${module}.${componentConfig.css.preprocessor}`,
componentName,
},
];
// --- Only get template if component option (withStyle, withTest, etc..) is true, or if template type is "component"
// converting boolean to string intentionally.
if (cmd.withTest.toString() === 'true') {
componentTemplates.push({
template: getTestingLibraryTemplate(componentName, componentConfig),
templateType: `Test "${componentName}.test.js"`,
componentPath: `${componentPathDir}/${componentName}.test.js`,
componentName,
});
}
if (cmd[componentTemplateType] || componentTemplateType === componentTemplateTypes.COMPONENT) {
const template = getComponentTemplate(cmd, cliConfigFile, componentName, componentTemplateType);
// converting boolean to string intentionally.
if (cmd.withStory.toString() === 'true') {
componentTemplates.push({
template: componentStoryTemplate,
templateType: `Story "${componentName}.stories.js"`,
componentPath: `${componentPathDir}/${componentName}.stories.js`,
componentName,
});
if (template) {
componentTemplates.push(template);
}
}
}
// converting boolean to string intentionally.
if (cmd.withLazy.toString() === 'true') {
componentTemplates.push({
template: componentLazyTemplate,
templateType: `Lazy "${componentName}.lazy.js"`,
componentPath: `${componentPathDir}/${componentName}.lazy.js`,
componentName,
});
}
generateComponentTemplates(componentTemplates);
}
module.exports = {
generateComponent,
};

@@ -1,38 +0,39 @@

import program from 'commander';
import chalk from 'chalk';
import pkg from '../package.json';
import { generateComponent } from './actions/componentActions';
import { getCLIConfigFile } from './services/configService';
const program = require('commander');
const chalk = require('chalk');
const pkg = require('../package.json');
const { generateComponent } = require('./actions/componentActions');
const { getCLIConfigFile } = require('./services/grcConfigService');
let commandNotFound = true;
export async function cli(args) {
module.exports = async function cli(args) {
const cliConfigFile = await getCLIConfigFile();
const { component } = cliConfigFile;
let commandNotFound = true;
program.version(pkg.version);
// Generate Component
// --- Generate Component
program
.command('component <name>')
.alias('c')
.option('-p, --path <path>', 'With specified path value', component.path || './src/components')
.option(
'-t, --withTest <withTest>',
'Would you like to create a corresponding test file with this component?',
component.test.withTest
)
.option(
'-s, --withStory <withStory>',
'Would you like to create a corresponding story file with this component?',
component.withStory
)
.option(
'-l, --withLazy <withLazy>',
'Would you like to create a corresponding lazy file (a file that lazy-loads your component out of the box and enables code splitting: https://reactjs.org/docs/code-splitting.html#code-splitting) with this component?',
component.withLazy
)
.action((componentName, cmd) => generateComponent(componentName, cmd, component))
.action(() => (commandNotFound = false));
.option('-p, --path <path>', 'The path where the component will get genereted in.', component.path)
.option('--withStyle', 'With corresponding test file.', component.css.withStyle)
.option('--no-withStyle', 'Without corresponding test file.')
.option('--withTest', 'With corresponding test file.', component.test.withTest)
.option('--no-withTest', 'Without corresponding test file.')
.option('--withStory', 'With corresponding story file.', component.withStory)
.option('--no-withStory', 'Without corresponding story file.')
.option('--withLazy', 'With corresponding lazy file.', component.withLazy)
.option('--no-withLazy', 'Without corresponding lazy file.')
.action((componentName, cmd) => generateComponent(cmd, cliConfigFile, componentName))
.action(() => {
commandNotFound = false;
});
program.parse(args);

@@ -45,2 +46,2 @@

}
}
};

Sorry, the diff of this file is not supported yet