Skip to content

Commit

Permalink
feat: 🎸 add new page command
Browse files Browse the repository at this point in the history
A new page command that will have its own configuration rules that you
can set up just like you did for the component command. You will also be
able to pass the same options to the page command that you are already
familiar with in the component command.

✅ Closes: #10
  • Loading branch information
arminbro committed Apr 19, 2020
1 parent c7795c5 commit 3a441de
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 59 deletions.
113 changes: 99 additions & 14 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,24 @@ When you run generate-react-cli within your project the first time, it will ask

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

Expand All @@ -79,16 +82,16 @@ This command will create a folder with your component name within your default (

#### Options

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

```
npx generate-react-cli c Box --withTest=false
npx generate-react-cli component Box --withTest=false
```

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

```
npx generate-react-cli c Box --withTest=true
npx generate-react-cli component Box --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.
Expand Down Expand Up @@ -140,6 +143,88 @@ 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 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).
29 changes: 25 additions & 4 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,44 @@ const { getCLIConfigFile } = require('./services/grcConfigService');

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

program.version(pkg.version);

// --- Generate Component
// --- 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.css.withStyle)
.option('--withTest <withTest>', 'With corresponding test file.', component.test.withTest)
.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));

program.parse(args);
};
37 changes: 20 additions & 17 deletions src/services/componentTemplateService.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ const componentTestTestingLibraryTemplate = require('../templates/component/comp
// private

function getComponentScriptTemplate({ cmd, cliConfigFile, componentName, componentPathDir }) {
const { component, usesTypeScript } = cliConfigFile;
const { cssPreprocessor, testLibrary, usesCssModule, usesTypeScript } = cliConfigFile;
const fileExtension = usesTypeScript ? 'tsx' : 'js';
let template = usesTypeScript ? componentTsTemplate : componentJsTemplate;

// --- If test library is not Testing Library or if withTest is false. Remove data-testid from template

if (component.test.library !== 'Testing Library' || !cmd.withTest) {
if (testLibrary !== 'Testing Library' || !cmd.withTest) {
template = template.replace(` data-testid="TemplateName"`, '');
}

// --- If it has a corresponding stylesheet

if (cmd.withStyle) {
const module = component.css.module ? '.module' : '';
const cssPath = `${componentName}${module}.${component.css.preprocessor}`;
const module = usesCssModule ? '.module' : '';
const cssPath = `${componentName}${module}.${cssPreprocessor}`;

// --- If the css module is true make sure to update the template accordingly

Expand All @@ -55,9 +55,9 @@ function getComponentScriptTemplate({ cmd, cliConfigFile, componentName, compone
}

function getComponentStyleTemplate({ cliConfigFile, componentName, componentPathDir }) {
const { component } = cliConfigFile;
const module = component.css.module ? '.module' : '';
const cssPath = `${componentName}${module}.${component.css.preprocessor}`;
const { cssPreprocessor, usesCssModule } = cliConfigFile;
const module = usesCssModule ? '.module' : '';
const cssPath = `${componentName}${module}.${cssPreprocessor}`;

return {
template: componentCssTemplate,
Expand All @@ -68,15 +68,15 @@ function getComponentStyleTemplate({ cliConfigFile, componentName, componentPath
}

function getComponentTestTemplate({ cliConfigFile, componentName, componentPathDir }) {
const { component, usesTypeScript } = cliConfigFile;
const { testLibrary, usesTypeScript } = cliConfigFile;
const fileExtension = usesTypeScript ? 'tsx' : 'js';
let template = null;

// --- Get test template based on test library type

if (component.test.library === 'Enzyme') {
if (testLibrary === 'Enzyme') {
template = componentTestEnzymeTemplate;
} else if (component.test.library === 'Testing Library') {
} else if (testLibrary === 'Testing Library') {
template = componentTestTestingLibraryTemplate.replace(/#|templateName/g, camelCase(componentName));
} else {
template = componentTestDefaultTemplate;
Expand Down Expand Up @@ -126,6 +126,16 @@ const componentTemplateTypes = {
COMPONENT: 'component',
};

// --- Template Map

const templateMap = {
[componentTemplateTypes.STYLE]: getComponentStyleTemplate,
[componentTemplateTypes.TEST]: getComponentTestTemplate,
[componentTemplateTypes.STORY]: getComponentStoryTemplate,
[componentTemplateTypes.LAZY]: getComponentLazyTemplate,
[componentTemplateTypes.COMPONENT]: getComponentScriptTemplate,
};

function generateComponentTemplates(componentTemplates) {
for (let i = 0; i < componentTemplates.length; i += 1) {
const { template, templateType, componentPath, componentName } = componentTemplates[i];
Expand Down Expand Up @@ -159,13 +169,6 @@ function generateComponentTemplates(componentTemplates) {

function getComponentTemplate(cmd, cliConfigFile, componentName, templateType) {
const componentPathDir = `${cmd.path}/${componentName}`;
const templateMap = {
[componentTemplateTypes.STYLE]: getComponentStyleTemplate,
[componentTemplateTypes.TEST]: getComponentTestTemplate,
[componentTemplateTypes.STORY]: getComponentStoryTemplate,
[componentTemplateTypes.LAZY]: getComponentLazyTemplate,
[componentTemplateTypes.COMPONENT]: getComponentScriptTemplate,
};

if (templateMap[templateType]) {
return templateMap[templateType]({ cmd, cliConfigFile, componentName, componentPathDir });
Expand Down
Loading

0 comments on commit 3a441de

Please sign in to comment.