ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

angular原理图学习

2022-05-29 14:04:33  阅读:157  来源: 互联网

标签:schematics name 原理图 hello 学习 json angular schema


安装

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

标签:schematics,name,原理图,hello,学习,json,angular,schema
来源: https://www.cnblogs.com/fangdongdemao/p/16323718.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有