Zapewne zauważyłeś/aś, że korzystając z takich komend jak:
1 |
ng g component cars/car-details |
komponent automatycznie utworzy się w katalogu src/app.
Chcemy uzyskać identyczny efekt – musimy nauczyć nasz Schematic, gdzie ma domyślnie tworzyć pliki. W ramach jednego pliku angular.json możemy mieć wiele projektów, więc wskażmy o jaki chodzi dokładnie. Oczywiście możesz w linii komend wskazać projekt, ale będzie to niewygodne i nieintuicyjne.
Tak wygląda przykładowy angular.json:
Zatem w przypadku aplikacji o nazwie platform, chodzi nam o wyjęcie klucza platform, np. poprzez:
1 |
Object.keys(projects)[0] |
To jest właśnie nazwa projektu. Stwórzmy zatem funkcję pomocniczą, która da nam dostęp do projektu i przygotuje nazwę i ścieżkę pobraną od użytkownika:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import { getWorkspace } from '@schematics/angular/utility/config'; import { buildDefaultPath, getProject } from '@schematics/angular/utility/project'; import { parseName } from '@schematics/angular/utility/parse-name'; import { SchematicsException, Tree, } from '@angular-devkit/schematics'; import { normalize } from '@angular-devkit/core'; // tworzymy helper - setupOtpions, można go wynieść go osobnego pliku export function setupOptions(tree: Tree, options: any): Tree { // korzystamy z utila getWorkspace, który wskazuje na root directory z plikiem angular.json const workspace = getWorkspace(tree); // jeśli użytkownik nie podał w konsoli projektu (czego obecnie nie obsługujemy) to zczytujemy pierwszy z pliku angular.json if (!options.project) { options.project = Object.keys(workspace.projects)[0]; } // jeśli nazwa projektu dalej nie jest zdefiniowana, to rzucamy wyjątek if (!options.project) { throw new SchematicsException('Option "project" is required.'); } // korzystamy z utila, który na podstawie workspace daje nam dostęp do projektu const project = getProject(workspace, options.project); // jeśli ścieżka do pliku tworzonego pliku nie została podana, to użyj domyślnej: src/app if (options.path === undefined) { options.path = normalize(buildDefaultPath(project)); // zwraca ścieżkę src/app } // jeśli została podana wraz z nazwą pliku np. shared/services/offers to użyjemy utila parseName, // który zwraca name bez ścieżki(tutaj offers) i odpowiednią ścieżkę (tutaj shared/services) const parsedPath = parseName(options.path, options.name); // nadpisujemy opcje z parametru options.name = parsedPath.name; options.path = parsedPath.path; return tree; } |
Kod do utilsów znajdziesz tutaj (getWorkspace, getProject, parseName, buildDefaultPath):
https://github.com/angular/angular-cli/tree/master/packages/schematics/angular/utility
Kod przykładu:
https://github.com/tomasznastaly/angular-schematics-tutorial/pull/2/files
TIP:
Jeśli chcesz umożliwić przekazanie projektu jako opcję, np:
1 |
ng g angularlove:http-service core/cars/car --project=platform |
to wystarczy dodać odpowiednie pole do schema.json:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "$schema": "http://json-schema.org/schema", "id": "AngularLoveHttpServiceSchematic", "title": "Creates a httpService Schematic.", "type": "object", "properties": { "path": {...}, "name": {...}, "project": { "type": "string", "description": "The name of the project.", "$default": { "$source": "projectName" } } } } |
Kod:
https://github.com/tomasznastaly/angular-schematics-tutorial/pull/3/files