Skip to content

Commit

Permalink
feat: 🎸 Make 'GRC' more configurable (multi component commands)
Browse files Browse the repository at this point in the history
GRC is now more configurable by allowing the developer to extend the
generate-react-cli.json config file with additional custom component
commands dynamically.

✅ Closes: #14
  • Loading branch information
arminbro committed May 10, 2020
1 parent 1d6f5ae commit 59f1622
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 157 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:

strategy:
matrix:
node-version: [8.x, 10.x, 12.x]
node-version: [10.x, 12.x]

steps:
- uses: actions/checkout@v1
Expand Down
139 changes: 51 additions & 88 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,66 @@ When you run generate-react-cli within your project the first time, it will ask
"testLibrary": "Testing Library",
"component": {
"path": "src/components",
"withLazy": false,
"withStory": false,
"withStyle": true,
"withTest": true,
"withStory": true,
"withLazy": false
},
"withTest": true
}
}
```

### Custom component commands:

By default, GRC comes with the one **component** command out of the box.

What if you wanted to generate components with your own custom commands like for example **page** or **layout** that have their own set of component config rules?

You can do so by extending the **generate-react-cli.json** config file like this.

```json
{
"usesTypeScript": false,
"usesCssModule": true,
"cssPreprocessor": "scss",
"testLibrary": "Testing Library",
"component": {
"path": "src/components",
"withLazy": false,
"withStory": false,
"withStyle": true,
"withTest": true
}
"page": {
"path": "src/pages",
"withLazy": true,
"withStory": false,
"withStyle": true,
"withTest": true,
"withTest": true
},
"layout": {
"path": "src/layout",
"withLazy": false,
"withStory": false,
"withLazy": true
"withStyle": false,
"withTest": true
}
}
```

Make sure to include the required properties listed below when creating the custom component commands. Otherwise, GRC will not register them as a custom component command.

The required properties are as follows:

- path
- withStyle
- withTest
- withStory
- withLazy

Once you have done that, you should be able to run the custom component commands like this:
`npx generate-react-cli page HomePage`
`npx generate-react-cli layout BoxLayout`

## Custom Templates

You can now create custom templates that Generate React CLI can use instead of the built-in templates that come with it. We hope this will provide more flexibility for your components and pages you want to generate.
Expand Down Expand Up @@ -236,88 +281,6 @@ Otherwise, if you don't pass any options, it will just use the default values fr
</tr>
</table>

### Generate Page

```
npx generate-react-cli page HomePage
```

This command will create a folder with your page name within your default (e.g. **src/pages**) directory, and its corresponding files.

#### **Example of the page files structure**

```
|-- /src
|-- /pages
|-- /HomePage
|-- HomePage.js
|-- HomePage.css
|-- HomePage.test.js
```

#### Options

You can also override some of the generate-react-cli default page config options using one-off commands. So for example, let's say you have set **withTest** to be `true` in the page config property. You can override it like this:

```
npx generate-react-cli page HomePage --withTest=false
```

Or vice versa, if you have set **withTest** to be `false` you can do this:

```
npx generate-react-cli page HomePage --withTest=true
```

Otherwise, if you don't pass any options, it will just use the default values from the generate-react-cli config file you have set.

<table>
<tr align="left">
<th>Options</th>
<th>Description</th>
<th>Value Type</th>
</tr>
<tr>
<td width="20%"><b>--path</b></td>
<td width="60%">
Value of the path where you want the page to be generated in (e.g. <b>src/pages</b>).
</td>
<td width="20%">String</td>
</tr>

<tr>
<td width="20%"><b>--withStyle</b></td>
<td width="60%">
Creates a corresponding stylesheet file with this page.
</td>
<td width="20%">Boolean</td>
</tr>

<tr>
<td width="20%"><b>--withTest</b></td>
<td width="60%">
Creates a corresponding test file with this page.
</td>
<td width="20%">Boolean</td>
</tr>

<tr>
<td width="20%"><b>--withStory</b></td>
<td width="60%">
Creates a corresponding (<a href="https://storybook.js.org">storybook</a>) story file with this page.
</td>
<td width="20%">Boolean</td>
</tr>

<tr>
<td width="20%"><b>--withLazy</b></td>
<td width="60%">
Creates a corresponding lazy file (a file that lazy-loads your page out of the box and enables <a href="https://reactjs.org/docs/code-splitting.html#code-splitting">code splitting</a>) with this page.
</td>
<td width="20%">Boolean</td>
</tr>
</table>

## License

Generate React CLI is open source software [licensed as MIT](https://github.com/arminbro/generate-react-cli/blob/master/LICENSE).
68 changes: 33 additions & 35 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,42 @@ const { getCLIConfigFile } = require('./services/grcConfigService');

module.exports = async function cli(args) {
const cliConfigFile = await getCLIConfigFile();
const { component, page } = cliConfigFile;

program.version(pkg.version);

// --- Generate component command

program
.command('component <name>')
.alias('c')

.option('-p, --path <path>', 'The path where the component will get genereted in.', component.path)
.option('--withStyle <withStyle>', 'With corresponding stylesheet file.', component.withStyle)
.option('--withTest <withTest>', 'With corresponding test file.', component.withTest)
.option('--withStory <withStory>', 'With corresponding story file.', component.withStory)
.option('--withLazy <withLazy>', 'With corresponding lazy file.', component.withLazy)

.action((componentName, cmd) => generateComponent(cmd, cliConfigFile, componentName));

// --- Generate page command

/**
* We can continue using the generateComponent method to generate pages.
* Afterall a page is a component at the end of the day.
*
* Eventually, if a page needs additional logic, we can create a new generatePage method.
*/

program
.command('page <name>')
.alias('p')

.option('-p, --path <path>', 'The path where the page will get genereted in.', page.path)
.option('--withStyle <withStyle>', 'With corresponding stylesheet file.', page.withStyle)
.option('--withTest <withTest>', 'With corresponding test file.', page.withTest)
.option('--withStory <withStory>', 'With corresponding story file.', page.withStory)
.option('--withLazy <withLazy>', 'With corresponding lazy file.', page.withLazy)

.action((pageName, cmd) => generateComponent(cmd, cliConfigFile, pageName));
// --- Generate component commands

Object.keys(cliConfigFile).forEach((configKey) => {
const configValue = cliConfigFile[configKey];

/**
* Check if each configValue is a component config
* and if it is, register it as a component command.
*/

if (
typeof configValue === 'object' &&
configValue.path !== undefined &&
configValue.withLazy !== undefined &&
configValue.withStory !== undefined &&
configValue.withStyle !== undefined &&
configValue.withTest !== undefined
) {
const commandName = configKey;
const commandOptions = configValue;

program
.command(`${commandName} <name>`)

.option('-p, --path <path>', 'The path where the component will get genereted in.', commandOptions.path)
.option('--withStyle <withStyle>', 'With corresponding stylesheet file.', commandOptions.withStyle)
.option('--withTest <withTest>', 'With corresponding test file.', commandOptions.withTest)
.option('--withStory <withStory>', 'With corresponding story file.', commandOptions.withStory)
.option('--withLazy <withLazy>', 'With corresponding lazy file.', commandOptions.withLazy)

.action((componentName, cmd) => generateComponent(cmd, cliConfigFile, componentName));
}
});

program.parse(args);
};
34 changes: 1 addition & 33 deletions src/services/grcConfigService.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,41 +67,9 @@ const componentLevelQuestions = [
},
];

// --- page level questions.

const pageLevelQuestions = [
{
type: 'input',
name: 'page.path',
message: 'Set the default path directory to where your pages will be generated in?',
default: () => 'src/pages',
},
{
type: 'confirm',
name: 'page.withStyle',
message: 'Would you like to create a corresponding stylesheet file with each page you generate?',
},
{
type: 'confirm',
name: 'page.withTest',
message: 'Would you like to create a corresponding test file with each page you generate?',
},
{
type: 'confirm',
name: 'page.withStory',
message: 'Would you like to create a corresponding story with each page you generate?',
},
{
type: 'confirm',
name: 'page.withLazy',
message:
'Would you like to create a corresponding lazy file (a file that lazy-loads your page out of the box and enables code splitting: https://reactjs.org/docs/code-splitting.html#code-splitting) with each page you generate?',
},
];

// --- merge all questions together.

const grcConfigQuestions = [...projectLevelQuestions, ...componentLevelQuestions, ...pageLevelQuestions];
const grcConfigQuestions = [...projectLevelQuestions, ...componentLevelQuestions];

async function createCLIConfigFile() {
try {
Expand Down

0 comments on commit 59f1622

Please sign in to comment.