🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
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
4.2.0

6

CHANGELOG.md

@@ -5,2 +5,8 @@ # Changelog

## [4.2.0](https://github.com/arminbro/generate-react-cli/compare/v4.1.1...v4.2.0) (2020-05-02)
### Features
- 🎸 Allow custom file templates ([6104241](https://github.com/arminbro/generate-react-cli/commit/610424136989b1f18de1e6fa9a04084114cde64b)), closes [#12](https://github.com/arminbro/generate-react-cli/issues/12)
### [4.1.1](https://github.com/arminbro/generate-react-cli/compare/v4.1.0...v4.1.1) (2020-04-23)

@@ -7,0 +13,0 @@

2

package.json
{
"name": "generate-react-cli",
"version": "4.1.1",
"version": "4.2.0",
"description": "A simple React CLI to generate components instantly and more.",

@@ -5,0 +5,0 @@ "repository": "https://github.com/arminbro/generate-react-cli",

@@ -16,3 +16,4 @@ # Generate React CLI

- Now supports React [TypeScript](https://www.typescriptlang.org/) projects.
- Now supports custom templates ([read more](#custom-templates)). 🎉
- Now supports React [TypeScript](https://www.typescriptlang.org/) 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.

@@ -40,3 +41,3 @@ - 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.

### e.g. **generate-react-cli.json**
### Example of the **generate-react-cli.json** config file:

@@ -66,2 +67,92 @@ ```json

## 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.
Both the `component` and `page` properties (within the **generate-react-cli.json** config file) can accept an optional `customTemplates` object property.
### Example of the `customTemplates` object:
```json
"customTemplates": {
"component": "templates/component.js",
"lazy": "templates/lazy.js",
"story": "templates/story.js",
"style": "templates/style.scss",
"test": "templates/test.js"
},
```
The keys represent the type of template, and the values are the paths that point to where your custom template lives in your project/system.
### Example of using the `customTemplates` property in the generate-react-cli.json config file:
```json
{
"usesTypeScript": false,
"usesCssModule": true,
"cssPreprocessor": "scss",
"testLibrary": "Testing Library",
"component": {
"customTemplates": {
"component": "templates/component/component.js",
"style": "templates/component/style.scss",
"test": "templates/component/test.js"
},
"path": "src/components",
"withStyle": true,
"withTest": true,
"withStory": true,
"withLazy": false
},
"page": {
"customTemplates": {
"test": "templates/page/test.js"
},
"path": "src/pages",
"withStyle": true,
"withTest": true,
"withStory": false,
"withLazy": true
}
}
```
Notice in the `page.customTemplates` that we only specified the "test" custom template type. That's because all the custom template types are optional. If you don't set the other types, the CLI will default to using the built-in templates it comes with.
### Example of a custom component template file:
```jsx
// templates/component/component.js
import React from 'react';
import styles from './TemplateName.module.css';
const TemplateName = () => (
<div className={styles.TemplateName} data-testid="TemplateName">
<h1>TemplateName component</h1>
</div>
);
export default TemplateName;
```
**Important** - Make sure to use the `TemplateName` keyword in your templates. The CLI will use this keyword to replace it with your component name.
### Example of a custom test template file:
```jsx
// templates/component/test.js
import React from 'react';
import ReactDOM from 'react-dom';
import TemplateName from './TemplateName';
it('It should mount', () => {
const div = document.createElement('div');
ReactDOM.render(<TemplateName />, div);
ReactDOM.unmountComponentAtNode(div);
});
```
## Usage

@@ -68,0 +159,0 @@

const chalk = require('chalk');
const replace = require('replace');
const { camelCase } = require('lodash');
const { existsSync, outputFileSync } = require('fs-extra');
const { existsSync, outputFileSync, readFileSync } = require('fs-extra');
const componentJsTemplate = require('../templates/component/componentJsTemplate');

@@ -17,32 +17,66 @@ const componentTsTemplate = require('../templates/component/componentTsTemplate');

function loadCustomTemplate(templatePath) {
// --- Try loading custom template
try {
const template = readFileSync(templatePath, 'utf8');
return template;
} catch (e) {
console.error(
chalk.red(
`
ERROR: The custom template path of "${templatePath}" does not exist.
Please make sure you're pointing to the right custom template path in your generate-react-cli.json config file.
`
)
);
return process.exit(1);
}
}
function getComponentScriptTemplate({ cmd, cliConfigFile, componentName, componentPathDir }) {
const { cssPreprocessor, testLibrary, usesCssModule, usesTypeScript } = cliConfigFile;
const { customTemplates } = cliConfigFile[cmd['_name']]; // get config property by command name
const fileExtension = usesTypeScript ? 'tsx' : 'js';
let template = usesTypeScript ? componentTsTemplate : componentJsTemplate;
let template = null;
// --- If test library is not Testing Library or if withTest is false. Remove data-testid from template
// Check for a custom component template.
if (testLibrary !== 'Testing Library' || !cmd.withTest) {
template = template.replace(` data-testid="TemplateName"`, '');
}
if (customTemplates && customTemplates.component) {
// --- Load and use the custom component template
// --- If it has a corresponding stylesheet
template = loadCustomTemplate(customTemplates.component);
} else {
// --- Else use GRC built-in component template
if (cmd.withStyle) {
const module = usesCssModule ? '.module' : '';
const cssPath = `${componentName}${module}.${cssPreprocessor}`;
template = usesTypeScript ? componentTsTemplate : componentJsTemplate;
// --- If the css module is true make sure to update the template accordingly
// --- If test library is not Testing Library or if withTest is false. Remove data-testid from template
if (module.length) {
template = template.replace(`'./TemplateName.module.css'`, `'./${cssPath}'`);
if (testLibrary !== 'Testing Library' || !cmd.withTest) {
template = template.replace(` data-testid="TemplateName"`, '');
}
// --- If it has a corresponding stylesheet
if (cmd.withStyle) {
const module = usesCssModule ? '.module' : '';
const cssPath = `${componentName}${module}.${cssPreprocessor}`;
// --- If the css module is true make sure to update the template accordingly
if (module.length) {
template = template.replace(`'./TemplateName.module.css'`, `'./${cssPath}'`);
} else {
template = template.replace(`{styles.TemplateName}`, `"${componentName}"`);
template = template.replace(`styles from './TemplateName.module.css'`, `'./${cssPath}'`);
}
} else {
template = template.replace(`{styles.TemplateName}`, `"${componentName}"`);
template = template.replace(`styles from './TemplateName.module.css'`, `'./${cssPath}'`);
// --- If no stylesheet, remove className attribute and style import from jsTemplate
template = template.replace(`className={styles.TemplateName} `, '');
template = template.replace(`import styles from './TemplateName.module.css';`, '');
}
} else {
// --- If no stylesheet, remove className attribute and style import from jsTemplate
template = template.replace(`className={styles.TemplateName} `, '');
template = template.replace(`import styles from './TemplateName.module.css';`, '');
}

@@ -58,9 +92,23 @@

function getComponentStyleTemplate({ cliConfigFile, componentName, componentPathDir }) {
function getComponentStyleTemplate({ cliConfigFile, cmd, componentName, componentPathDir }) {
const { customTemplates } = cliConfigFile[cmd['_name']]; // get config property by command name
const { cssPreprocessor, usesCssModule } = cliConfigFile;
const module = usesCssModule ? '.module' : '';
const cssPath = `${componentName}${module}.${cssPreprocessor}`;
let template = null;
// Check for a custom style template.
if (customTemplates && customTemplates.style) {
// --- Load and use the custom style template
template = loadCustomTemplate(customTemplates.style);
} else {
// --- Else use GRC built-in style template
template = componentCssTemplate;
}
return {
template: componentCssTemplate,
template,
templateType: `Stylesheet "${cssPath}"`,

@@ -72,3 +120,4 @@ componentPath: `${componentPathDir}/${cssPath}`,

function getComponentTestTemplate({ cliConfigFile, componentName, componentPathDir }) {
function getComponentTestTemplate({ cliConfigFile, cmd, componentName, componentPathDir }) {
const { customTemplates } = cliConfigFile[cmd['_name']]; // get config property by command name
const { testLibrary, usesTypeScript } = cliConfigFile;

@@ -78,5 +127,11 @@ const fileExtension = usesTypeScript ? 'tsx' : 'js';

// --- Get test template based on test library type
// Check for a custom test template.
if (testLibrary === 'Enzyme') {
if (customTemplates && customTemplates.test) {
// --- Load and use the custom test template
template = loadCustomTemplate(customTemplates.test);
} else if (testLibrary === 'Enzyme') {
// --- Else use GRC built-in test template based on test library type
template = componentTestEnzymeTemplate;

@@ -97,8 +152,22 @@ } else if (testLibrary === 'Testing Library') {

function getComponentStoryTemplate({ cliConfigFile, componentName, componentPathDir }) {
function getComponentStoryTemplate({ cliConfigFile, cmd, componentName, componentPathDir }) {
const { usesTypeScript } = cliConfigFile;
const { customTemplates } = cliConfigFile[cmd['_name']]; // get config property by command name
const fileExtension = usesTypeScript ? 'tsx' : 'js';
let template = null;
// Check for a custom story template.
if (customTemplates && customTemplates.story) {
// --- Load and use the custom story template
template = loadCustomTemplate(customTemplates.story);
} else {
// --- Else use GRC built-in story template
template = componentStoryTemplate;
}
return {
template: componentStoryTemplate,
template,
templateType: `Story "${componentName}.stories.${fileExtension}"`,

@@ -110,8 +179,22 @@ componentPath: `${componentPathDir}/${componentName}.stories.${fileExtension}`,

function getComponentLazyTemplate({ cliConfigFile, componentName, componentPathDir }) {
function getComponentLazyTemplate({ cliConfigFile, cmd, componentName, componentPathDir }) {
const { usesTypeScript } = cliConfigFile;
const { customTemplates } = cliConfigFile[cmd['_name']]; // get config property by command name
const fileExtension = usesTypeScript ? 'tsx' : 'js';
let template = null;
// Check for a custom lazy template.
if (customTemplates && customTemplates.lazy) {
// --- Load and use the custom lazy template
template = loadCustomTemplate(customTemplates.lazy);
} else {
// --- Else use GRC built-in lazy template
template = usesTypeScript ? componentTsLazyTemplate : componentLazyTemplate;
}
return {
template: usesTypeScript ? componentTsLazyTemplate : componentLazyTemplate,
template,
templateType: `Lazy "${componentName}.lazy.${fileExtension}"`,

@@ -118,0 +201,0 @@ componentPath: `${componentPathDir}/${componentName}.lazy.${fileExtension}`,