Schreiben Sie Ihre eigene CLI für React

Wenn Sie jedes Mal Ctrl+C drücken, wenn Sie eine neue Komponente in der Reaktion erstellen, ist dieser Artikel genau das Richtige für Sie!



Die Reaktion hat keine eigene CLI, und es ist verständlich, warum. Es gibt keine spezifischen Regeln, wie die Struktur der Komponente aussehen soll, es gibt nur allgemeine Empfehlungen in der Dokumentation. Alle Entwickler verwenden eine Struktur, die in ihrem Team Wurzeln geschlagen hat. Und manchmal muss man Projekte in verschiedenen Stilen unterstützen.


Die Struktur selbst hängt auch vom verwendeten Stack ab:


  • Stile - gestylt, SCSS-Module, CSS;
  • TypeScript oder JavaScript;
  • Tests

Es gibt verschiedene Möglichkeiten, um Ihnen das Erstellen neuer Komponenten zu erleichtern. Beispielsweise können Sie Vorlagen in Ihrer Entwicklungsumgebung erstellen (z. B. in WebStorm). Heute schauen wir uns jedoch an, wie eine vollständige Komponentenstruktur über die Befehlszeile erstellt wird. Am Ende des Artikels können wir Komponenten mit einem einzigen Befehl erstellen. Zum Beispiel wie:


 npm run create components/Home/ComponentName 

Vorbereitung


Wir werden die Create React App verwenden , um das Projekt zu erstellen .


Erstellen Sie ein Projekt:


 npx create-react-app react-cli 

Alle unsere Codes werden in einer Datei gespeichert. Wir erstellen den Ordner cli im Stammverzeichnis unseres Projekts und in der Datei create.js.


Um zu arbeiten, benötigen wir 3 Module, die wir in unsere Datei importieren.


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

fs - Modul zum Arbeiten mit dem Dateisystem.


path - Modul zur Verarbeitung von Dateipfaden.


Minimist - ein Modul zum Konvertieren von Argumenten über die Befehlszeile.


Arbeite mit Argumenten


Um eine Komponente zu erstellen, müssen Sie den Pfad und den Namen der Komponente an die Befehlszeile übergeben. Wir übertragen diese Informationen in einer Zeile ( z. B. components/folder1/folder2/Menu ), die wir dann mit dem Pfad und dem Namen analysieren.


Alle Argumente können aus dem process abgerufen process . Angenommen, wir geben die folgende Zeile in die Konsole ein:


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

Als Ergebnis erhalten wir:


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

Mit dem Minimist-Modul können wir die Argumente in ein Objekt konvertieren:


 // 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' // } 

Toll, damit kannst du schon arbeiten.


Verzeichnisse erstellen


Bereiten Sie zunächst die erforderlichen Variablen vor. Wir benötigen den vollständigen Pfad zum src-Ordner unseres Projekts, den Pfad aus den Argumenten als Array und den Namen der Komponente.


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

Angenommen, wir haben einen nicht vorhandenen Pfad angegeben. In guter Weise müssen wir alle diese Unterordner erstellen, wenn sie nicht vorhanden sind. Also lass es uns tun.


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

Hier durchlaufen wir alle Elemente des Pfads und erstellen bei Bedarf ein Verzeichnis mit der Methode mkdirSync . Vorher normalisieren wir den Pfad zur Komponente in einer Zeile mit der Methode resolve . Nach diesen Vorgängen erstellen wir die erforderliche Verzeichnisstruktur.


Test geschrieben. Wir geben den folgenden Befehl in die Befehlszeile ein (gleichzeitig haben wir noch keine Verzeichnisse im src Ordner):


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

Und wir bekommen folgendes Ergebnis:



Erstellen von Komponentendateien


Gut gemacht, fertig, alles, was bleibt, ist die Erstellung der Komponentendateien.


Wir werden die einfachste Komponentenstruktur verwenden:


  • Für Styles nur CSS
  • Ohne TS
  • Keine Tests
  • Funktionskomponente

Es stellt sich heraus, dass wir 3 Dateien erstellen müssen.


1. Komponentenvorlage


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

2. Indexdateivorlage


 export { default } from './CustomComponent'; 

3. Formatvorlage


 .wrapper {} 

Lassen Sie uns zunächst den vollständigen Pfad zur Komponente (einschließlich des persönlichen Ordners der Komponente) in einer Variablen abrufen:


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

Neue Dateien werden mit dem writeFileSync , der den Dateipfad und den Inhalt übernimmt.


Erstellen einer Komponentendatei:


 // 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); 

Erstellen einer Indexdatei:


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

Stylesheet erstellen:


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

Fertig


Nun wollen wir sehen, was passiert ist.


 // 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); 

Es stellte sich heraus, nur 43 Zeilen, unter Berücksichtigung der Kommentare, nicht schlecht für so eine nützliche Sache!


Versuchen wir nun, eine Komponente zu erstellen:


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


Alles hat geklappt! Da ist die letzte Berührung ...


Hinzufügen eines Befehls zu package.json


Fügen Sie den Befehl zur Datei package.json hinzu, damit nicht jedes Mal der Pfad zum Skript geschrieben wird


 { "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" ] } } 

Jetzt statt:


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

wir können einfach schreiben


 npm run create components/folder1/folder2/Button 

Der Quellcode des Projekts kann auf dem Github eingesehen werden

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


All Articles