• angular原理图学习


    安装

    npm install -g @angular-devkit/schematics-cli
    

    创建原理图

    schematics blank --name=hello-world
    

    运行原理图

    先执行npm run build然后运行原理图

    schematics 文件夹地址:原理图名称 --<required-option>=<value>
    

    demo

    schematics .:hello-world   // 可以看package.json 添加的文件
    schematics ./src/collection.json:hello-world
    

    在执行一个命令, 创造一个新的原理图

    schematics blank --name=goodbye-world
    

    collection.json

    描述收集的原理图的模式。每个原理图都使用名称、描述和工厂功能创建。

    {
      "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
      "schematics": {
        "hello-world": {
          "description": "A blank schematic.",
          "factory": "./hello-world/index#helloWorld"
        },
        "goodbye-world": {
          "description": "A blank schematic.",
          "factory": "./goodbye-world/index#goodbyeWorld"
        }
      }
    }
    

    $schema属性指定 CLI 用于验证的架构。

    schematics 出了属于该集合的命名原理图。每个原理图都有一个纯文本描述,并指向主文件中生成的入口函数。

    factory属性指向生成的入口函数。在本例中,您通过调用工厂函数来调用hello-world原理图。

    #helloWorld 就是执行对应的helloWorld()函数

    下面两个还不知道怎么用

    • 可选 schema属性指向一个 JSON 模式文件,该文件定义了可用于原理图的命令行选项。

      • type:属性提供的类型的描述符。
      • properties:定义原理图可用选项的对象。
    • 可选aliases数组指定一个或多个可用于调用原理图的字符串。例如,Angular CLI“generate”命令的原理图有一个别名“g”,它允许你使用命令ng g

    package.json导入

    {
      "name": "my-lib",
      "version": "0.0.1",
      "schematics": "./src/collection.json",// 这个是为了知道原理图从哪里导入的
    }
    

    添加一个js

    案例

    schema.ts

    export interface Schema {
      name: string
    }
    
    
    import {Schema} from "./schema";
    
    export function helloWorld(_options: Schema): Rule {
      return (tree: Tree, _context: SchematicContext) => {
     +   tree.create('hello.js',`console.log('Hello-World')`)
        return tree;
      };
    }
    
    1. helloWorld() 是原理图入口函数, 是一个规则工厂,返回一个创建规则(Rule) 的高阶函数
    2. Rule: 定义一个函数, 接受一个Tree进行变换, 返回新的Tree
    3. Tree: 虚拟文件系统,就是文件
    4. SchematicContext 原理图上下文, 每个原理图都在自己的上下文中运行

    执行yarn build 在执行schematics .:hello-world

    我们发现原理图生成hello.js 文件, 但是现实中没有, 就是原理图在debug 模式下执行的

    当我们执行 schematics .:hello-world --debug=false

    我们会发现生成了hello.js

    再执行这条命令, 我们发现控制带会报错, 我们必须删除这个文件才能运行

    为了防止我们每次生成都要构建, 修改 package.json

    "build:watch": "tsc -p tsconfig.json --watch",

    创建 xxx/schema.json

    {
      "$schema": "http://json-schema.org/schema",
      "$id": "SchematicsMyService",
      "title": "My Service Schema",
      "type": "object",
      "description": "The name of the service.",
      "properties": {
        "name": {
          "description": "The name of the service.",
          "type": "string",
          "$default": {
            "$source": "argv",
            "index": 0
          },
          "x-prompt": "输入你需要执行的名称?"
        }
      },
      "required": [
        "name"
      ]
    }
    
    

    导入collection.json

    "schematics": {
        "hello-world": {
          "description": "A blank schematic.",
          "factory": "./hello-world/index#helloWorld",
       +   "schema": "./hello-world/schema.json"
        }
      }
    

    执行 schematics .:hello-world --debug=false

    输入名称 xxx

    检查我们生成的 js文件

    使用原理图模块

    ./files/文件夹下使用, 如果不用filestemplate 必须在tsconfig.json 进行调整

    __name@dasherize__

    name变量与正常字符串的其余部分分开

    dasherize是一个辅助函数,它将接收name变量的值并将其转换为 kebab case 字符串,并且@是将变量应用于辅助函数的一种方法。

    name-age ===> name-age

    classify 好像让每一个首字母大写

    name-age ===> NameAge

    camelize 首字母小写,其他类似驼峰的形式

    name-age ===> nameAge

    <%= xxx %>

    1. 创建hello-__name@dasherize__.ts

      console.log('Hello <%= name %>')
      
      import { Component } from '@angular/core';
      
      @Component({
        selector: 'hello-<%= dasherize(name) %>',
      })
      export class Hello<%= classify(name) %>Component {
        console.log('Hello <%= name %>')
      }
      
    2. index.ts

      import {strings} from '@angular-devkit/core';
      import {apply, mergeWith, Rule, SchematicContext, template, url} from '@angular-devkit/schematics';
      import {Schema} from "./schema";
      
      
      // You don't have to export the function as default. You can also have more than one rule factory
      // per file.
      export function helloWorld(_options: Schema): Rule {
        return (_, _context: SchematicContext) => {
          // const {name} = _options
          // tree.create('hello.js', `console.log('Hello-${name}')`)
          const sourceTemplates = url('./files');
          const sourceParametrized = apply(sourceTemplates, [
            template({
              ..._options,
              ...strings
            })
          ])
          // return tree;
          return mergeWith(sourceParametrized)
        };
      }
      
    3. 其实我们可以使用任意的自定义函数

      import {Injectable} from '@angular/core';
      import {Observable} from "rxjs";
      import {HttpClient} from "@angular/common/http";
      
      const API_URL = '/api/<%= dasherize(name) %>'
      
      @Injectable({
        providedIn: 'root'
      })
      // <%= classify(name) %>  NameAge
      // <%= camelize(name) %>  nameAge
      // <%= dasherize(name) %>  name-age
      
      export class <%= classify(name) %>Service {
        constructor(private httpClient: HttpClient) {
        }
      
        findAll(): Observable<<%= classify(name) %>[]> {
          return this.httpClient.get<<%= classify(name) %>[]>(API_URL);
        }
      
        create(<%= camelize(name) %>: <%= classify(name) %>): Observable<number> {
          return this.httpClient.post<number>(API_URL, <%= camelize(name) %>);
        }
      
      }
      
      export interface <%= classify(name) %> {
        someProperty: string;
      }
      
    4. 执行命令schematics .:hello-world name-age --debug=false

    判断 transform

    schema.json

     "properties": {
         ...
         + "transform": {
         +   "type": "boolean",
         +   "default": "false"
         +  }
     }
    

    添加类型 schema.ts

    export interface Schema {
      name: string;
     +  transform?:boolean;
    }
    

    使用

       <% if(transform){ %>
        		 let a=1
          <% }else{ %>
       			 let b=2
          <% } %>
    

    使用命令

     schematics .:hello-world name-age true --debug=false  
    第二个参数的使用
    

    上个完整点的案例

    抄抄源码

    https://github.com/angular/angular-cli/tree/main/packages/schematics/angular/component/files
    

    新建一个__name@dasherize__文件夹

    __name@dasherize__.component.ts.template 文件

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-<%= dasherize(name) %>',
      templateUrl: './<%= dasherize(name) %>.component.html',
      styleUrls: ['./<%= dasherize(name) %>.component.scss']
    })
    export class <%=classify(name)%>Component implements OnInit {
    
      constructor() { }
    
      ngOnInit() {
      }
    }
    

    原理图-文件夹下新建 schema.json

    {
        "$schema": "http://json-schema.org/schema",
        "id": "componentSchema",
        "title": "component options schema.",
        "type": "object",
        "descripiton": "创建一个component范本",
        "properties": {
            "name": {
                "description": "component的名字.",
                "type": "string",
                "$default": {
                    "$source": "argv",
                    "index": 0
                },
                "x-prompt": "你想创建的component的名字:"
            }
        },
        "required": [
            "name"
        ]
    }
    

    id:这个模式定义在集合中的唯一 id。
    title:一个人类可读的模式描述。
    type:由这些属性提供的类型描述符。
    properties:一个定义该原理图可用选项的对象。
    required:必填的选项

    注意属性(proerties)选项:
      $default 的设定,上面的表示,如果没有指定输入的选项,那么输入的第一个就是 name
       x-prompt:如果没有输入选项,则提示语提示输入

    创建好 schema.json 之后,一定要记得在 collection.json 中配置 schema 属性

      "schematics": {
        "hello-world": {
          "description": "A blank schematic.",
          "factory": "./hello-world/index#helloWorld",
        +  "schema": "./hello-world/schema.json"
        }
      }
    

    新建一个schema.ts

    export interface Schema {
        name: string;
    }
    

    编写规则工厂逻辑代码

    yarn add @schematics/angular -S
    

    https://swmlee.com/2019/12/12/technicalessays/angular-schematics-tutorial/

    https://github.com/angular/angular-cli/blob/main/packages/schematics/angular/component/index.ts

    angular schematics 实现 ng add 指令安装模块

    抄源码一个完整的案例

    schematics ./ng-hello/src/collection.json:c   age --project=angualr12date1120
    

    取消--project xxxx 就使用默认angular.jsondefaultProject 自带的项目名

    这里介绍的一种schema.json中参数的使用

    打包到ng g 的命令里

    package.json

    {
      "name": "ng-hello",
      "version": "0.0.0",
      "description": "A blank schematics",
      "scripts": {
        "build": "tsc -p tsconfig.schematics.json",
        "postbuild": "copyfiles package.json schematics/*/schema.json schematics/*/files/** schematics/collection.json ../dist/ng-hello/"
      },
      "keywords": [
        "schematics"
      ],
      "schematics": "./schematics/collection.json", // ng g xxx   找到的入口文件是这个
      "ng-add": {
        "save": "devDependencies"
      },
      "devDependencies": {
        "@types/node": "^12.11.1",
        "@types/jasmine": "~3.10.0",
        "jasmine": "^4.0.0",
        "copyfiles": "file:../../node_modules/copyfiles",
        "typescript": "file:../../node_modules/typescript"
      }
    }
    
    

    ../dist 注意对应打包生成的文件夹

    执行yarn build 会自动跟着执行postbuild 指令执行,

    或者"build:p": "tsc -p tsconfig.schematics.json & npm run postbuild",

    tsconfig.schematics.json

    {
      "compilerOptions": {
        "baseUrl": ".",
        "lib": [
          "es2018",
          "dom"
        ],
        "declaration": true,
        "module": "commonjs",
        "moduleResolution": "node",
        "noEmitOnError": true,
        "noFallthroughCasesInSwitch": true,
        "noImplicitAny": true,
        "noImplicitThis": true,
        "noUnusedParameters": true,
        "noUnusedLocals": true,
        "rootDir": "schematics",
        "outDir": "../../dist/my-lib-one/schematics",// 打包后的出口文件
        "skipDefaultLibCheck": true,
        "skipLibCheck": true,
        "sourceMap": true,
        "strictNullChecks": true,
        "target": "es6",
        "types": [
          "jasmine",
          "node"
        ]
      },
      "include": [
        "schematics/**/*"
      ],
      "exclude": [
        "schematics/*/files/**/*"
      ]
    }
    

    然后把ng-hello 包丢到node_modules 里面

    执行ng g ng-hello:xxx 执行命令

    其实我们也可以执行生成打包丢到node_modules 里面然后执行使用

    记得别用src 文件夹, 要schematincs 文件夹 这样就跟 ng g 的保持一致

    测试的时候到最外层的package.json上, 因为要用到angular.json

    schematics ./ng-hello/schematics/collection.json:c age

    /**
     * 构建用于生成的默认项目路径。
     * @param项目将生成其默认路径的项目。
     */
    export function buildDefaultPath(project: workspaces.ProjectDefinition): string {
      const root = project.sourceRoot ? `/${project.sourceRoot}/` : `/${project.root}/src/`;
      const projectDirName =
        project.extensions['projectType'] === ProjectType.Application ? 'app' : 'lib';
    
      return `${root}${projectDirName}`;
    }
    // 如果没有执行path就是用默认的,project是angular.json里面的, 如果默认指令--project的名称就使用默认的
    // project.sourceRoot 默认是`src`  所以 root 是 /src/
    // 所有我们知道最后输入的是  /src/app
    export enum ProjectType {
      Application = 'application',
      Library = 'library',
    }
    

    --style less

    找到对应的模块find-module.ts

    对应的代码

    https://github.com/973782523/angualr-schematics
    

    如果在vue使用

    npm install @angular/cli -D
    
    yarn add typescript copyfiles -D
    

    记得在src添加一个文件夹app

    或者你在angualr.json 修改app 改成你对应的文件

    cd ng-hello
    // 打包ts
    yarn build-watch2
    // 打包其他文件
    yarn build:p  每次修改代码的时候,记得执行这个命令进行测试
    ng g ng-hello:c age1 --skip-import
    

    写了一个vue的案例

    https://github.com/973782523/vue3-schematics
    
  • 相关阅读:
    基础薄弱的反思
    最短路SPFA
    乌龟棋
    石子归并
    Linux学习2
    java 基础 数组
    java 基础 异常
    java 基础 接口
    java 基础 instance of
    solidity“abi.encode/abi.encodePacked”使用golang编码
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/16323718.html
Copyright © 2020-2023  润新知