Üdvözlet, Angular fejlesztők! Ha valaha is úgy érezted, hogy túl sok időt töltesz ismétlődő kódok írásával, komponensek, szolgáltatások vagy modulok boilerplate-jének felállításával, akkor jó helyen jársz. Az Angular keretrendszer egyik legkevésbé kihasznált, mégis hihetetlenül erőteljes eszköze az Angular Schematics, amely forradalmasíthatja a fejlesztési munkafolyamatodat. Készülj fel, mert ma mélyre merülünk abban, hogyan készíthetsz saját Schematics-et a kódgenerálás automatizálásához, és hogyan növelheted jelentősen a fejlesztői hatékonyságodat.
Mi az az Angular Schematics és Miért Fontos?
Az Angular Schematics egy kódgeneráló és kódmódosító motor, amely lehetővé teszi, hogy sablonok és szabályok alapján automatizáljuk a gyakori feladatokat a projektünkben. Gondolj rá úgy, mint egy varázslatos robotra, amely elvégzi helyetted a repetitív kódolást, miközben fenntartja a projekt egységességét. Valójában az Angular CLI parancsok (mint az ng generate component
vagy ng new
) is Schematics-eket használnak a háttérben.
De miért is van erre szükséged? Íme néhány nyomós ok:
- Konzisztencia: Biztosítja, hogy az összes újonnan generált fájl és kód kövesse a vállalatod vagy csapatod által meghatározott legjobb gyakorlatokat és stílusirányelveket. Nincs többé vita a mappastruktúráról vagy a fájlnevekről.
- Sebesség és Hatékonyság: Jelentősen felgyorsítja a fejlesztést azáltal, hogy a boilerplate kód pillanatok alatt létrejön. Kevesebb gépelés, több fókusz a valódi üzleti logikára.
- Hibacsökkentés: Az automatizált folyamatok minimalizálják az emberi hibák esélyét, amelyek a manuális kódmásolás során könnyen előfordulhatnak.
- Refaktorálás és Migráció: Nem csak generálásra alkalmas! Schematics-ekkel automatikusan módosíthatod vagy refaktorálhatod a meglévő kódot, ami rendkívül hasznos lehet egy nagyobb átalakítás vagy API változás esetén.
Előkészületek: Mire lesz szükséged?
Mielőtt belevágnánk a Schematics írásába, győződj meg róla, hogy a következő eszközök telepítve vannak a gépeden:
- Node.js és npm: Ezek elengedhetetlenek a JavaScript/TypeScript fejlesztéshez és a csomagkezeléshez.
- Angular CLI: Noha a Schematics önállóan is használható, az Angular CLI kényelmes felületet biztosít a futtatásukhoz és az Angular projektkörnyezet kezeléséhez. Telepítsd a
npm install -g @angular/cli
paranccsal. - Nx (Opcionális, de Ajánlott): Az Nx egy kiterjesztett monorepo eszköz, amely nagyszerűen kezeli a Schematics projekteket, és számos beépített funkciót kínál. Ha egy nagyobb projekten dolgozol, érdemes megfontolni.
A Schematics Munkaterület Beállítása
Két fő módja van egy Schematics projekt létrehozásának:
1. Schematics Munkaterület Létrehozása az Nx Segítségével (Ajánlott)
Ha már használsz Nx-et, vagy szeretnél egy monorepo struktúrában dolgozni, ez az út a legegyszerűbb:
npx create-nx-workspace my-schematics-workspace --preset=angular --appName=my-angular-app
cd my-schematics-workspace
nx generate @nx/angular:library --name=my-schematics --publishable --importPath=@my-org/my-schematics
Ez létrehoz egy új Angular munkaterületet, majd egy publikálható könyvtárat, ami ideális a Schematics tárolására. Az Nx automatikusan konfigurálja a buildelést és a tesztelést.
2. Standalone Schematics Munkaterület Létrehozása
Ha csak egy Schematics-et szeretnél létrehozni egy már meglévő Angular projekthez, vagy önállóan kezelni, akkor a schematics-cli
a barátod:
npm install -g @angular-devkit/schematics-cli
schematics blank my-custom-schematics
cd my-custom-schematics
npm install
Ez egy üres Schematics projektet hoz létre, amely tartalmazza a szükséges alapfájlokat.
A Schematics Struktúrája: Ahol a Varázslat Kezdődik
Nézzük meg, milyen kulcsfontosságú fájlok alkotják egy Schematics projektet:
collection.json
: A Belépési Pont
Ez a fájl az összes Schematics listáját tartalmazza, amit a projekt kínál. Itt definiálod a Schematics nevét, leírását, és hogy melyik TypeScript fájl implementálja azt.
{
"$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"my-component-generator": {
"description": "Generál egy új komponenst a mi stílusunkban.",
"factory": "./src/my-component-generator/index#myComponentGenerator",
"schema": "./src/my-component-generator/schema.json"
}
}
}
Itt a my-component-generator
a Schematics neve, amit az ng generate
paranccsal használni fogunk. A factory
megadja a TypeScript fájl útvonalát és az exportált függvény nevét, ami a Schematics logikát tartalmazza. A schema
pedig a bemeneti paraméterek definícióját írja le.
schema.json
: A Bemeneti Paraméterek Definíciója
Ez a JSON Schema fájl határozza meg, milyen beállításokat fogadhat el a Schematics, és milyen típusúaknak kell lenniük. Ezek az opciók kerülnek majd átadásra a Schematics logikájának.
{
"$schema": "http://json-schema.org/schema",
"id": "MyComponentGeneratorSchema",
"title": "My Component Generator Options",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "A generálandó komponens neve.",
"x-prompt": "Mi legyen a komponens neve?",
"$default": {
"$source": "argv",
"index": 0
}
},
"path": {
"type": "string",
"description": "Az útvonal, ahova a komponenst generálni kell.",
"default": "src/app",
"format": "path"
},
"flat": {
"type": "boolean",
"description": "Ne hozzon létre külön mappát a komponensnek.",
"default": false
}
},
"required": [
"name"
]
}
A properties
objektumban definiálhatod az összes elfogadott opciót. Az x-prompt
lehetővé teszi, hogy interaktív kérdést tegyél fel a felhasználónak, ha az opciót nem adták meg a parancssorban.
index.ts
: A Szabálygyár (Rule Factory)
Ez a TypeScript fájl tartalmazza a Schematics legfontosabb logikáját. Itt definiálod azokat a szabályokat (Rules), amelyek a projekt fájlrendszerét módosítják. Minden Schematics egy factory function-ből indul, ami egy Rule
-t ad vissza.
import { Rule, SchematicContext, Tree, apply, url, applyTemplates, move, mergeWith, forEach, FileEntry } from '@angular-devkit/schematics';
import { strings } from '@angular-devkit/core';
interface MyComponentGeneratorSchema {
name: string;
path: string;
flat: boolean;
}
export function myComponentGenerator(options: MyComponentGeneratorSchema): Rule {
return (tree: Tree, _context: SchematicContext) => {
// 1. Definiáld a template-ek forrását
const sourceTemplates = url('./files');
// 2. Alkalmazd a template-eket és a transzformációkat
const transformedTemplates = apply(sourceTemplates, [
applyTemplates({
...options,
...strings, // `classify`, `dasherize`, `camelize` stb. segédfüggvények
}),
move(options.flat ? options.path : `${options.path}/${strings.dasherize(options.name)}`),
// Esetlegesen egyéb fájlkezelési logikák
]);
// 3. Egyesítsd a generált fájlokat a meglévő Tree-vel
return mergeWith(transformedTemplates)(tree, _context);
};
}
Nézzük meg a kulcsfogalmakat:
Rule
: Egy függvény, ami egyTree
-t fogad el, és egy újTree
-t (vagy egy Promise-t/Observable-t, ami egyTree
-vel oldódik fel) ad vissza. Ez a Schematics lényege.Tree
: A fájlrendszer absztrakciója. Két részből áll: abase
Tree (a jelenlegi fájlrendszer állapota) és acommitted
Tree (a végrehajtásra váró változások). A Schematics sosem módosítja közvetlenül a fájlrendszert, hanem aTree
-n keresztül dolgozik.SchematicContext
: Információkat és segédfüggvényeket biztosít a Schematics végrehajtási környezetéről (pl. logolás, taskok futtatása).
Template Fájlok (pl. src/my-component-generator/files
mappa)
Ezek a fájlok tartalmazzák a generálandó kód sablonjait. Speciális szintaxissal (EJS-szerű) injektálhatsz változókat és logikát.
Például egy __name__.component.ts.template
fájlban:
import { Component, OnInit } from '@angular/core';
@Component({
selector: '',
templateUrl: './.component.html',
styleUrls: ['./.component.scsscss'],
})
export class Component implements OnInit {
constructor() {}
ngOnInit(): void {}
}
Figyeld meg a __name__
konvenciót a fájlnévben és a <%= ... %>
interpolációt a tartalomban. A strings
segédfüggvények (dasherize
, classify
) rendkívül hasznosak a névadási konvenciók betartásához.
Fájlkezelési Műveletek és Közös Segédfüggvények
A Schematics rengeteg beépített segédfüggvényt kínál a fájlrendszer manipulálásához:
url('./files')
: Betölti a megadott útvonalon lévő template fájlokat.apply(source, [rules...])
: Alkalmaz egy sorRule
-t egySource
-ra (pl. egy template gyűjteményre).applyTemplates({ ...options, ...strings })
: Ez egyRule
, ami a template-ekben lévő változókat a megadott opciókkal és astrings
segédfüggvényekkel helyettesíti.move(path)
: Ez egyRule
, ami áthelyezi a fájlokat egy új célútvonalra.mergeWith(source, strategy)
: Ez egyRule
, ami egyesíti asource
(pl. generált fájlok) tartalmát a jelenlegiTree
-vel. Astrategy
(pl.OverwriteStrategy.Overwrite
vagyOverwriteStrategy.AllowForbidden
) meghatározza, hogyan kezelje az ütközéseket.chain([rule1, rule2, ...])
: Egy sorRule
láncolására szolgál, szekvenciálisan hajtja végre őket.externalSchematic('collection-name', 'schematic-name', options)
: Lehetővé teszi, hogy egy másik Schematics-et hívj meg a sajátodból. Ez nagyon hasznos a modularitás szempontjából.
Fájlok Módosítása: Túl a Generáláson
A Schematics nem csak új fájlokat tud létrehozni, hanem meglévőket is módosíthat. Ez a legkomplexebb, de egyben legizgalmasabb része is:
- Text alapú módosítás: Egyszerűbb esetekben, például egy
package.json
frissítésénél, elegendő lehet a fájl tartalmát stringként kezelni és reguláris kifejezésekkel módosítani. - Abstract Syntax Tree (AST) alapú módosítás: Ez a legrobosztusabb és leginkább ajánlott módszer TypeScript fájlok módosítására. Az
@schematics/angular
számos segédfüggvényt biztosít ehhez, például:getSourceFile(tree, path)
: Betölti egy TypeScript fájl AST-jét.addDeclarationToModule(source, path, declarationName, modulePath)
: Hozzáad egy komponenst/direktívát egy modulhoz.addImportToModule()
,addExportToModule()
: Hasonlóan importok és exportok hozzáadására.- A
Change
interfész és aInsertChange
,ReplaceChange
osztályok segítségével precízen tudsz módosításokat végrehajtani a kódban.
Az AST módosításokhoz mélyebb ismeret szükséges a TypeScript compiler API-ról, de a pontosságuk és a refaktorálási képességeik páratlanok.
Példa: Egy Egyszerű Komponens Generátor
Vegyük a fentebb bemutatott példát, és nézzük meg, hogyan áll össze egy egyszerű komponensgenerátor:
-
src/my-component-generator/index.ts
:import { Rule, SchematicContext, Tree, apply, url, applyTemplates, move, mergeWith } from '@angular-devkit/schematics'; import { strings } from '@angular-devkit/core'; interface ComponentOptions { name: string; path: string; flat: boolean; style: 'css' | 'scss' | 'less' | 'none'; // Kiegészítjük a stílus opcióval } export function myComponentGenerator(options: ComponentOptions): Rule { return (tree: Tree, _context: SchematicContext) => { // 1. Alapértelmezett értékek kezelése, pl. ha nincs megadva útvonal options.path = options.path || 'src/app'; options.style = options.style || 'css'; // Alapértelmezett stílus const templateSource = apply(url('./files'), [ applyTemplates({ ...options, ...strings, }), move(options.flat ? options.path : `${options.path}/${strings.dasherize(options.name)}`), ]); // Opcionálisan: frissítsük az Angular modult, hogy regisztráljuk a komponenst // Ehhez bonyolultabb AST manipulációra lenne szükség, ami meghaladja // ennek a példának a kereteit. Használhatjuk az @schematics/angular // beépített segédjeit, mint az addDeclarationToModule. return mergeWith(templateSource)(tree, _context); }; }
-
src/my-component-generator/schema.json
:{ "$schema": "http://json-schema.org/schema", "id": "MyComponentGeneratorSchema", "title": "My Component Generator Options", "type": "object", "properties": { "name": { "type": "string", "description": "A komponens neve.", "x-prompt": "Mi legyen a komponens neve?", "$default": { "$source": "argv", "index": 0 } }, "path": { "type": "string", "description": "A komponens útvonala.", "default": "src/app", "format": "path" }, "flat": { "type": "boolean", "description": "Ne hozzon létre külön mappát.", "default": false }, "style": { "type": "string", "description": "A stílus formátuma.", "enum": ["css", "scss", "less", "none"], "default": "css" } }, "required": ["name"] }
-
src/my-component-generator/files/__name__.component.ts.template
:import { Component, OnInit } from '@angular/core'; @Component({ selector: '', templateUrl: './.component.html', styleUrls: ['./.component.scsscss'], }) export class Component implements OnInit { constructor() {} ngOnInit(): void {} }
-
src/my-component-generator/files/__name__.component.html.template
:<p><%= dasherize(name) %> works!</p>
-
src/my-component-generator/files/__name__.component.scsscss.template
:/* Component styles for <%= dasherize(name) %> */ :host { display: block; }
Ezután futtathatod a Schematics-edet az Nx workspace-ben:
nx generate my-schematics:my-component-generator my-new-component --path=src/app/features --style=scss
Vagy standalone projektben (először buildeld a Schematics-et, majd linkeld, vagy futtasd direktben a schematics
paranccsal, ha éppen fejleszted):
npm run build
schematics ./:my-component-generator my-new-component --path=src/app/features --style=scss
Schematics Tesztelése
A Schematics tesztelése elengedhetetlen a megbízható működéshez. A @angular-devkit/schematics/testing
modul eszközöket biztosít ehhez:
import { SchematicTestRunner, RunSchematicOptions } from '@angular-devkit/schematics/testing';
import * as path from 'path';
const collectionPath = path.join(__dirname, '../collection.json');
describe('my-component-generator', () => {
const runner = new SchematicTestRunner('schematics', collectionPath);
it('generates files for a new component', async () => {
const tree = await runner.runSchematicAsync('my-component-generator', { name: 'test-comp', path: 'src/app' }, Tree.empty());
expect(tree.files.length).toBe(3); // .ts, .html, .css (vagy scss)
expect(tree.files).toEqual(expect.arrayContaining([
'/src/app/test-comp/test-comp.component.ts',
'/src/app/test-comp/test-comp.component.html',
'/src/app/test-comp/test-comp.component.css',
]));
});
it('generates flat component', async () => {
const tree = await runner.runSchematicAsync('my-component-generator', { name: 'flat-comp', path: 'src/app', flat: true }, Tree.empty());
expect(tree.files).toEqual(expect.arrayContaining([
'/src/app/flat-comp.component.ts',
'/src/app/flat-comp.component.html',
'/src/app/flat-comp.component.css',
]));
});
});
A SchematicTestRunner
segítségével futtathatod a Schematics-edet egy virtuális Tree
-n, és ellenőrizheted a generált fájlokat és azok tartalmát.
Publikálás és Használat
Miután elkészültél és letesztelted a Schematics-edet, itt az ideje használni:
- Helyi használat: Ha egy Angular projektben dolgozol, és a Schematics-ed is a projekt része (pl. egy Nx könyvtárban), akkor az
ng generate
parancs automatikusan megtalálja. Pl.:ng generate my-lib:my-component-generator
. - npm publikálás: A Schematics csomagokat is publikálhatod az npm-re. A
package.json
-ben meg kell adnod aschematics
mezőt, ami acollection.json
-re mutat.{ "name": "my-custom-schematics", "version": "1.0.0", "description": "My custom Angular Schematics", "schematics": "./collection.json", "private": false, "scripts": { "build": "tsc -p tsconfig.json" } }
Ezután egyszerűen futtasd az
npm publish
parancsot (ügyelj a verziószámra!). Mások ezután telepíthetik a csomagodat (npm install my-custom-schematics
), és használhatják a Schematics-edet:ng generate my-custom-schematics:my-component-generator
.
Gyakorlati Tippek és Bevált Módszerek
- Kezdj kicsiben: Ne próbálj azonnal komplex Schematics-et írni. Kezdj egyszerű fájlgenerálással, majd fokozatosan építsd tovább.
- Használd ki az Angular CLI Schematics-eit: Ha valamilyen alap Angular funkciót szeretnél módosítani, vagy csak annak működését akarod reprodukálni, nézz bele az
@schematics/angular
forráskódjába. Rengeteg hasznos példát és segédfüggvényt találsz ott. - Moduláris felépítés: Bonyolultabb Schematics-ek esetén érdemes a logikát kisebb, újrafelhasználható
Rule
-okra bontani. Achain
és azexternalSchematic
segít ebben. - Hibakezelés és validáció: Mindig validáld a bejövő opciókat a
schema.json
-ben és a Schematics logikájában. Kezeld a lehetséges hibákat, és adj értelmes visszajelzést a felhasználónak. - Dokumentáció: Dokumentáld a Schematics-edet! Írd le, mire való, milyen opciókat fogad el, és hogyan kell használni.
- Tesztelés, tesztelés, tesztelés: Ahogy a komplexitás növekszik, a tesztek válnak a megbízhatóság alapjává.
Összefoglalás
Az Angular Schematics egy game-changer eszköz a fejlesztés automatizálásában és a csapatok közötti konzisztencia biztosításában. Bár a kezdeti tanulási görbe meredeknek tűnhet az AST manipuláció és a Tree
fogalmának megértése miatt, a befektetett idő megtérül a hosszú távú hatékonyság és a jobb kódminőség formájában.
Kezdj el kísérletezni, automatizáld a repetitív feladatokat, és emeld magasabb szintre az Angular fejlesztésedet! Ne feledd, a cél az, hogy a gépek a gépi munkát végezzék, te pedig a kreatív problémamegoldásra koncentrálj.
Remélem, ez a részletes útmutató segít neked abban, hogy magabiztosan vágj bele a saját Angular Schematics-ed elkészítésébe. Jó kódolást!
Leave a Reply