2
votes

Chemin relatif des schémas angulaires

Je voudrais créer un schéma personnalisé pour Angular qui créera un fichier dans le même répertoire que celui à partir duquel le schéma a été exécuté. J'ai suivi cet article, mais je ne sais pas comment j'obtiendrais le nouveau fichier à ajouter dans le répertoire souhaité. ( https: //developer.okta .com / blog / 2019/02/13 / angular-schematics # create-your-first-schematic )

Par exemple, si j'ai la structure de répertoires suivante:

export function setupOptions(host: Tree, options: any): Tree {
  const workspace = getWorkspace(host);
  if (!options.project) {
    options.project = Object.keys(workspace.projects)[0];
  }
  const project = workspace.projects[options.project];
  options.path = join(normalize(project.root), 'src');
  return host;
}

// You don't have to export the function as default. You can also have more than one rule factory
// per file.
export function myComponent(_options: any): Rule {
  return (tree: Tree, _context: SchematicContext) => {
    setupOptions(tree, _options);
    const movePath = normalize(_options.path + '/');
    const templateSource = apply(url('./files/src'), [
      template({ ..._options }),
      move(movePath),
      forEach((fileEntry: FileEntry) => {
        if (tree.exists(fileEntry.path)) {
          tree.overwrite(fileEntry.path, fileEntry.content);
        }
        return fileEntry;
      })
    ]);
    const rule = mergeWith(templateSource, MergeStrategy.Overwrite);
    return rule(tree, _context);
  };
}


2 commentaires

cela devrait fonctionner par défaut en utilisant le cli ng . Pouvez-vous poster votre usine?


J'ai ajouté l'usine ci-dessus.


3 Réponses :


1
votes

Ajoutez ceci à votre schema.json

{
 ...,
 "properties": {
  ..
  "path": {
   "type": "string",
   "format": "path",
   "description": "The path to create the simple schematic within.",
   "visible": false
  }


0 commentaires

0
votes

Suivez les étapes mentionnées dans la documentation angulaire Vous rencontrerez quelques problèmes. Par exemple

1) const workspaceConfig = tree.read ('/ angular.json');

// sera nul lors de l'utilisation de la commande 'schematics' mais fonctionnera lors de l'utilisation de la virgule 'ng g'.

2) De la même manière, 'options.path' ne sera pas défini lors de l'utilisation de la commande 'schematics' mais fonctionnera avec la commande 'ng g'.

La réponse ci-dessus est correcte, vous devez ajouter le chemin vers le fichier schema.json puis dans votre fonction

'export function myComponent (_options: any): Rule {' p>

vous devriez pouvoir utiliser 'options.path' pour obtenir l'emplacement actuel. Cependant, comme je l'ai mentionné, je n'ai pas pu le faire fonctionner en utilisant la commande «schematics». Je n'ai pu le faire fonctionner qu'en utilisant la commande 'ng g'.

Voici donc à titre d'exemple mes fichiers

1) ..schematics / ng-generate / customComponent / schema.json

import {
  Rule, Tree, SchematicsException,
  apply, url, applyTemplates, move,
  chain, mergeWith
} from '@angular-devkit/schematics';

import { strings, experimental, normalize } from '@angular-devkit/core';

import { Schema as CustomSchema } from './schema';

export function generate(options: CustomSchema): Rule {
    return (tree: Tree) => {
        const workspaceConfig = tree.read('/angular.json'); // will return null when using schematics command but will work when using ng g
        console.log('workspaceConfig::', workspaceConfig);
        console.log('path:', options.path); // will be undefined when using schematics command but will work when using ng g
        
        // from now following along with angular docs with slight modifications. 
        if (workspaceConfig && !options.path) {
            const workspaceContent = workspaceConfig.toString();
            console.log('workspaceContent::', workspaceContent);
            
            const workspace: experimental.workspace.WorkspaceSchema = JSON.parse(workspaceContent);
            console.log('workspace', workspace);
            
            options.project = workspace.defaultProject;
            const projectName = options.project as string;
            const project = workspace.projects[projectName];
            const projectType = project.projectType === 'application' ? 'app' : 'lib';
            console.log('projectType::', projectType);
            
            options.path = `${project.sourceRoot}/${projectType}`;
        }

        
        if (options.path) { 
           // this will be used by the ng g command
            const templateSource = apply(url('./files'), [
                applyTemplates({
                    classify: strings.classify,
                    dasherize: strings.dasherize,
                    name: options.name
                }),
                move(normalize(options.path as string))
            ]);
            return chain([
                mergeWith(templateSource)
            ]);
        } else {
            // this will be used by the schematics command
            const templateSource = apply(url('./files'), [
                applyTemplates({
                    classify: strings.classify,
                    dasherize: strings.dasherize,
                    name: options.name
                })
            ]);
            return chain([
                mergeWith(templateSource)
            ]);
        }
    };
}

2) ..schematics / ng-generate / customComponent / schema.ts

import { Schema as ComponentSChema } from '@schematics/angular/component/schema';

export interface Schema extends ComponentSChema {
    // The name of the custom component
    name: string;
}

2) ..schematics / ng-generate / customComponent / index.ts

{
    "$schema": "http://json-schema.org/schema",
    "id": "GenerateCustomComponent",
    "title": "Generate Custom Component",
    "type": "object",
    "properties": {
        "name": {
            "description": "The name for the custom component.",
            "type": "string",
            "x-prompt": "What is the name for the custom component?"
        },
        "path": {
            "type": "string",
            "format": "path",
            "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.",
            "visible": false
        }
    },
    "required": [
        "name"
    ]
}


0 commentaires

0
votes

Quelque chose qui m'a dérouté pendant un certain temps et à surveiller.

'options.path' ne sera pas défini lors de l'exécution d'une commande schématique dans la racine du projet angulaire. Ce n'est que si vous avez changé de répertoire dans le sous-répertoire de la racine que le chemin sera disponible.


0 commentaires