Écrire votre propre CLI pour React

Si vous faites Ctrl+C chaque fois que vous créez un nouveau composant dans la réaction, cet article est pour vous!



La réaction n'a pas sa propre CLI, et on comprend pourquoi. Il n'y a pas de règles spécifiques sur l'apparence de la structure du composant, il n'y a que des recommandations générales dans la documentation. Tous les développeurs utilisent une structure qui a pris racine dans leur équipe. Et parfois, vous devez soutenir des projets dans différents styles.


La structure elle-même dépend également de la pile utilisée:


  • Styles - style, modules scss, css;
  • TypeScript ou JavaScript;
  • Les tests

Il existe plusieurs façons de vous faciliter la vie lors de la création de nouveaux composants. Par exemple, vous pouvez créer des modèles dans votre environnement de développement (par exemple, dans WebStorm). Mais aujourd'hui, nous allons voir comment créer une structure complète de composants à partir de la ligne de commande. À la fin de l'article, nous pourrons créer des composants avec une seule commande. Par exemple, comme:


 npm run create components/Home/ComponentName 

La préparation


Nous utiliserons l'application Create React pour créer le projet .


Créez un projet:


 npx create-react-app react-cli 

Tout notre code sera stocké dans un seul fichier. Nous créons le dossier cli à la racine de notre projet, et à l'intérieur du fichier create.js.


Pour fonctionner, nous avons besoin de 3 modules, nous les importons dans notre fichier.


 // cli/create.js const fs = require('fs'); const path = require('path'); const minimist = require('minimist'); 

fs - module pour travailler avec le système de fichiers.


path - module de traitement des chemins de fichiers.


minimist - un module pour convertir des arguments à partir de la ligne de commande.


Travailler avec des arguments


Pour créer un composant, nous devons transmettre le chemin et le nom du composant à la ligne de commande. Nous transférerons ces informations sur une seule ligne ( par exemple, components/folder1/folder2/Menu ), que nous analyserons ensuite le chemin et le nom.


Tous les arguments peuvent être récupérés à partir de l'objet de process . Supposons que nous entrions la ligne suivante dans la console:


 node cli/create.js --path components/folder/Menu 

En conséquence, nous obtenons:


 console.log(process.argv); // [ // '/usr/local/bin/node', // '/Users/a17105765/projects/react-cli/cli/create.js', // '--path', // 'components/folder/Menu' // ] 

En utilisant le module minimist, nous pouvons convertir les arguments en un objet:


 // cli/create.js // ... const args = minimist(process.argv); console.log(args); // { // _: [ // '/usr/local/bin/node', // '/Users/a17105765/projects/react-cli/cli/create.js' // ], // path: 'components/folder/Menu' // } 

Très bien, vous pouvez déjà travailler avec cela.


Création de répertoires


Préparez d'abord les variables nécessaires. Nous avons besoin du chemin complet vers le dossier src de notre projet, le chemin des arguments sous forme de tableau et le nom du composant.


 // cli/create.js // ... //     src   const srcPath = [__dirname, '..', 'src']; //         const arrPath = args.path.split('/'); //     ( ) const componentName = arrPath[arrPath.length - 1]; 

Supposons que nous ayons indiqué un chemin inexistant. Dans le bon sens, nous devons créer tous ces sous-dossiers s'ils ne sont pas là. Alors faisons-le.


 // cli/create.js // ... //     ( ) const currentArray = []; arrPath.forEach(element => { currentArray.push(element); const currentResolvePath = path.resolve(...srcPath, ...currentArray); if (!fs.existsSync(currentResolvePath)) { //  -     ? fs.mkdirSync(currentResolvePath); //  ,    } }); 

Ici, nous parcourons tous les éléments du chemin et, si nécessaire, créons un répertoire à l'aide de la méthode mkdirSync . Avant cela, nous normalisons le chemin d'accès au composant sur une seule ligne à l'aide de la méthode de resolve . Après avoir effectué ces opérations, nous créerons la structure de répertoires nécessaire.


Test écrit. Nous entrons la commande suivante dans la ligne de commande (en même temps, nous n'avons pas encore de répertoires dans le dossier src ):


 node cli/create.js --path components/A/B/C/D/E/CustomComponent 

Et nous obtenons le résultat suivant:



Création de fichiers de composants


Bien joué, terminé, il ne reste plus qu'à créer les fichiers des composants.


Nous utiliserons la structure de composant la plus simple:


  • Pour les styles CSS simples
  • Sans TS
  • Aucun test
  • Composant fonctionnel

Il s'avère que nous devons créer 3 fichiers.


1. Modèle de composant


 import React from 'react'; import './CustomComponent.css'; const CustomComponent = () => { return ( <div className="wrapper"> </div> ); }; export default CustomComponent; 

2. Modèle de fichier d'index


 export { default } from './CustomComponent'; 

3. Modèle de fichier de style


 .wrapper {} 

Pour commencer, obtenons le chemin d'accès complet au composant (y compris le dossier personnel du composant) dans une variable:


 // cli/create.js // ... const componentPath = [...srcPath, ...arrPath]; 

Les nouveaux fichiers sont créés à l'aide de la writeFileSync , qui prend le chemin et le contenu du fichier.


Création d'un fichier composant:


 // cli/create.js // ... const componentCode = `import React from 'react'; import './${componentName}.css'; const ${componentName} = () => { return ( <div className="wrapper"> </div> ); }; export default ${componentName};`; fs.writeFileSync(path.resolve(...componentPath, `${componentName}.jsx`), componentCode); 

Création d'un fichier d'index:


 // cli/create.js // ... const indexCode = `export { default } from './${componentName}';`; fs.writeFileSync(path.resolve(...componentPath, 'index.js'), indexCode); 

Création d'une feuille de style:


 // cli/create.js // ... const styleCode = '.wrapper {}'; fs.writeFileSync(path.resolve(...componentPath, `${componentName}.css`), styleCode); 

C'est fait!


Voyons maintenant ce qui s'est passé.


 // cli/create.js const fs = require('fs'); //       const path = require('path'); //     const minimist = require('minimist'); //        const args = minimist(process.argv); const srcPath = [__dirname, '..', 'src']; //    src   const arrPath = args.path.split('/'); //         const componentName = arrPath[arrPath.length - 1]; //   -   //     ( ) const currentArray = []; arrPath.forEach(element => { currentArray.push(element); const currentResolvePath = path.resolve(...srcPath, ...currentArray); if (!fs.existsSync(currentResolvePath)) { //  -     ? fs.mkdirSync(currentResolvePath); //  ,    } }); const componentPath = [...srcPath, ...arrPath]; //   const componentCode = `import React from 'react'; import './${componentName}.css'; const ${componentName} = () => { return ( <div className="wrapper"> </div> ); }; export default ${componentName};`; fs.writeFileSync(path.resolve(...componentPath, `${componentName}.jsx`), componentCode); //    const indexCode = `export { default } from './${componentName}';`; fs.writeFileSync(path.resolve(...componentPath, 'index.js'), indexCode); //    const styleCode = '.wrapper {}'; fs.writeFileSync(path.resolve(...componentPath, `${componentName}.css`), styleCode); 

Il ne s'est avéré que 43 lignes, compte tenu des commentaires, pas mal pour une chose aussi utile!


Essayons maintenant de créer un composant:


 node cli/create.js --path components/folder1/folder2/Button 


Tout a fonctionné! Il y a la dernière touche ...


Ajout d'une commande à package.json


Ajoutez la commande au fichier package.json pour qu'à chaque fois nous n'écrivions pas le chemin du script


 { "name": "react-cli", "version": "0.1.0", "private": true, "dependencies": { "react": "^16.12.0", "react-dom": "^16.12.0", "react-scripts": "3.2.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "create": "node cli/create.js --path" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } } 

Maintenant au lieu de:


 node cli/create.js --path components/folder1/folder2/Button 

on peut juste écrire


 npm run create components/folder1/folder2/Button 

Le code source du projet peut être consulté sur le github

Source: https://habr.com/ru/post/fr477780/


All Articles