LoginSignup
3
0

More than 5 years have passed since last update.

Schematicsでちょっとだけgenerateされるファイルをカスタマイズ

Last updated at Posted at 2019-02-15

発端

ng g s --name myでservice作る時に

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class MyService {

  constructor() { }
}

が作られますが

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: null
})
export class MyService {

  constructor() { }
}

としたいなぁと。
少しだけ変更したいだけなので、もともとのパラメータの役割とかも引き継ぎたい。そんな時
ng g --helpをして出てくる schematicを利用して試してみる。

$ ng g --help
Generates and/or modifies files based on a schematic.
usage: ng generate <schematic> [options]

arguments:
  schematic
    The schematic or collection:schematic to generate.

options:
  --defaults
    When true, disables interactive input prompts for options with a default.
  --dry-run (-d)
    When true, runs through and reports activity without writing out results.
  --force (-f)
    When true, forces overwriting of existing files.
  --help
    Shows a help message for this command in the console.
  --interactive
    When false, disables interactive input prompts.

やってみた

npm i -g @angular-devkit/schematics-cliしたり
schematics blank my-schematicsしたり

等の説明は省略します。

構成としてはこんな感じで作ります。

my-schematics
├── README.md
├── package-lock.json
├── package.json
├── src
│   ├── collection.json
│   ├── component
│   │   ├── files
│   │   │   └── __name@dasherize@if-flat__
│   │   │       ├── __name@dasherize__.component.__styleExt__.template
│   │   │       ├── __name@dasherize__.component.html.template
│   │   │       ├── __name@dasherize__.component.spec.ts.template
│   │   │       └── __name@dasherize__.component.ts.template
│   │   ├── index.ts
│       ├── index_spec.ts
│   │   ├── schema.json
│   │   └── schema.ts
│   └── service
│       ├── files
│       │   └── __name@dasherize@if-flat__
│       │       ├── __name@dasherize__.service.spec.ts.template
│       │       └── __name@dasherize__.service.ts.template
│       ├── index.ts
│       ├── index_spec.ts
│       ├── schema.json
│       └── schema.ts
└── tsconfig.json

npm i @schematics/angular@schematics/angularを入れておきます。

my-schematics/src/collection.ts
{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "component": {
      "aliases": [ "c" ],
      "description": "create component",
      "factory": "./component",
      "schema": "./component/schema.json"
    },
    "service": {
      "aliases": [ "s" ],
      "description": "create service",
      "factory": "./service",
      "schema": "./service/schema.json"
    }
  }
}

my-schematics/src/service/index.ts
import { Rule, chain } from '@angular-devkit/schematics';

import buildService from '@schematics/angular/service';
import { Schema as ServiceOptions } from './schema';

export default function (options: ServiceOptions): Rule {

  return chain([
    buildService( {...options} ),
  ]);
}
my-schematics/src/service/schema.ts
import { Schema as ServiceSchema } from '@schematics/angular/service/schema';

export interface Schema extends ServiceSchema {
  root?: boolean;
}
my-schematics/src/service/schema.json
{
  "$schema": "http://json-schema.org/schema",
  "id": "SchematicsAngularService",
  "title": "Angular Service Options Schema",
  "type": "object",
  "description": "Creates a new, generic service definition in the given or default project.",
  "properties": {
    "name": {
      "type": "string",
      "description": "The name of the service.",
      "$default": {
        "$source": "argv",
        "index": 0
      },
      "x-prompt": "What name would you like to use for the service?"
    },
    "path": {
      "type": "string",
      "format": "path",
      "description": "The path at which to create the service, relative to the workspace root.",
      "visible": false
    },
    "project": {
      "type": "string",
      "description": "The name of the project.",
      "$default": {
        "$source": "projectName"
      }
    },
    "flat": {
      "type": "boolean",
      "default": true,
      "description": "When true (the default), creates files at the top level of the project."
    },
    "spec": {
      "type": "boolean",
      "default": true,
      "description": "When true (the default), generates a  \"spec.ts\" test file for the new service.",
      "x-deprecated": "Use \"skipTests\" instead."
    },
    "skipTests": {
      "type": "boolean",
      "description": "When true, does not create \"spec.ts\" test files for the new service.",
      "default": false
    },
    "lintFix": {
      "type": "boolean",
      "default": false,
      "description": "When true, applies lint fixes after generating the pipe."
    },
    "root": "--- 追加部分 ---",
    "root": {
      "type": "boolean",
      "default": false,
      "description": "When true, provided in will be 'root'. If not null"
    }
  },
  "required": [
    "name"
  ]
}

my-schematics/src/service/files/__name@dasherize@if-flat__/__name@dasherize__.service.ts.template
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: <% if(root) { %>'root'<% } else { %>null<% } %>
})
export class <%= classify(name) %>Service {

  constructor() { }
}

これでnpm run buildし、あとはpublishするなり、privateや相対パスリポジトリとしてinstallするなりします。

installしたプロジェクト内で
ng g my-schematics:service --name my

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: null
})
export class MyService {

  constructor() { }
}

ng g --helpすると使えるschematicsとして一覧に追加される

$ ng g --help
Generates and/or modifies files based on a schematic.
usage: ng generate <schematic> [options]

arguments:
  schematic
    The schematic or collection:schematic to generate.

options:
  --defaults
    When true, disables interactive input prompts for options with a default.
  --dry-run (-d)
    When true, runs through and reports activity without writing out results.
  --force (-f)
    When true, forces overwriting of existing files.
  --help
    Shows a help message for this command in the console.
  --interactive
    When false, disables interactive input prompts.

Available Schematics:
  Collection "my-schematics" (default):
    appShell
    application
    class
    component
    directive
    enum
    guard
    interface
    library
    module
    pipe
    service
    serviceWorker
    universal

続く

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0