最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 使用 Angular Schematics 快速生成模板代码

    正文概述 掘金(NEKOI)   2021-07-10   450

    准备

    1. 全局安装 @angular-devkit/schematics-cli 以使用 schematics 命令
    $ npm install -g @angular-devkit/schematics-cli
    
    1. 创建新的Schematics项目
    $ schematics blank <schematic-name>
    

    在已生成的Schematics工程根目录下调用该命令会快速添加一个以填写的<schematic-name>命名的schematic空白模板,并在collection.json中添加相应基础信息。

    步骤

    创建一个Schematics初始工程

    $ schematics blank my-schematics
    $ cd my-schematics
    $ npm i
    

    1. Schematics文件构成

    /src/collection.json

    collection.json 文件是整个Schematics的主要定义文件,并且包含该库中所有可用schematic模板的定义。

    {
      "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
      "schematics": {
        "my-schematics": {
          "description": "A blank schematic.",
          "factory": "./my-schematics/index#mySchematics"
           
        }
      }
    }
    
    • description:描述该Schematic模板
    • factory:指明该Schematic模板入口。从该文件可以看出,生成的Schematics初始工程默认提供了一个同名的my-schematics模板,指向./my-schematics/index文件并特别指向mySchematics函数。也可以仅使用 "factory": "./my-schematics/index", 需要将index.tsexport function mySchematics(){}更改为export default function(){}

    附加属性:

    • aliases(可选):指定该Schematic模板的一个或多个别名,以string数组表示。
    • schema(可选):指明每个Schematic模板单独的schema和所有的可用的命令行选项参数。

    另外,注意Schematics工程中package.json有一个schematic属性指向 collection.json 文件。

    index.ts

    import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
    // 可以不用将本函数设置为默认导出,同一文件中可以有多个 rule factory
    // 这是一个 schematic 工厂函数,最终返回一个 rule
    export function mySchematics(_options: any): Rule {
      return (tree: Tree, _context: SchematicContext) => {
        // schematic rule 会被 Tree 和 Schematic context 调用
        // rule 会把对文件的变换处理添加到 Tree 上,返回处理后的 Tree 给下一条 rule,这就是说,schematic rule 是可组合的
        return tree;
      };
    }
    

    schema.json (需要时手动创建)

    {
      "$schema": "http://json-schema.org/schema",
      "$id": "MyFirstSchematic",
      "title": "Hello Option Schema",
      "type": "object",
      "description": "My First Schematic",
      "properties": {
        "name": {                               // 参数名
          "type": "string",                     // 参数类型
          "description": "The name of file",    // 参数描述
          "$default": {                         // 设为默认参数
            "$source": "argv",                  // 从命令行命令传入
            "index": 0                          // 在命令中的默认位置。
            // 例如:schematics .:my-schematics Mirai (默认位置) 
            // 对比 schematics .:my-schematics --name=Mirai (标准传入形式)
          },
          "x-prompt": "Who do we want to greet?" // 未传入该位置参数时的交互提示
        }
      },
      "required": [
        "name"
      ]
    }
    

    2. Schematics 相关基本概念

    factory

    工厂函数将接受一些自定义的参数 _options 并返回一条规则。

    Rule

    规则是通过Tree和SchematicContext调用的,并且可以调用其他已经实现的规则。一旦被调用,规则将对树进行调整,并将其返回以供进一步处理。

    Tree

    Tree 是工作空间中每个文件的虚拟表示。使用虚拟树而不是直接操作文件有以下一些优势:1)只有在每个 schematic 都成功运行的情况下,我们才会提交对树的更改。 2)在 debug 模式下(使用 --dry-run 标识),可以预览文件的改动而不影响实际的文件系统。 3)I/O 操作仅发生在整个处理过程结束后。


    3. 从一个简单的例子体验Schematics

    让我们从默认生成的 /src/my-schematics 模板开始体验。

    //index.ts
    export function mySchematics(_options: any): Rule {
      return (tree: Tree, _context: SchematicContext) => {
        tree.create('hello.js', `console.log('Hello Schematics');`);
        return tree;
      };
    }
    

    构建并在当前工程根目录下运行:

    $ npm run build
    $ schematics .:my-schematics
    

    运行结果:显示 CREATE hello.js (32 bytes) 但没有实际文件生成。

    原因:在使用相对路径调用schematics时默认为调试模式,每次使用时需要添加 --debug=false--dry-run=false 关闭调试模式。

    再次调用 schematics .:my-schematics --debug=false,至此,成功生成一个 hello.js 文件,其内容为 console.log('Hello Schematics');


    4. 向schematics传入自定义选项

    /src/my-schematics下创建schema.json,添加以下代码。这里我们以自定义一个name参数为例。

    {
      "$schema": "http://json-schema.org/schema",
      "$id": "MyFirstSchematic",
      "title": "Hello Option Schema",
      "type": "object",
      "description": "My First Schematic",
      "properties": {
        "name": {
          "type": "string",
          "description": "The name of file",
          "$default": {
            "$source": "argv",
            "index": 0
          },
          "x-prompt": "Who do we want to greet?"
        }
      },
      "required": [
        "name"
      ]
    }
    

    collection.json 中引入创建的 schema.json

    {
      "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
      "schematics": {
        "my-schematics": {
          "description": "A blank schematic.",
          "factory": "./my-schematics/index#mySchematics",
          "schema": "./my-schematics/schema.json"           // add this
        }
      }
    }
    

    同时,也可以创建一个 schema.d.ts 来为我们的原理图提供代码及类型的检查。

    export interface Schema{
      name: string;
    }
    

    随后于 index.ts 中引入并使用定义的Schema类型(function mySchematics(_options: Schema): Rule)。

    import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
    import { Schema } from './schema';
    
    export function mySchematics(_options: Schema): Rule {
      return (tree: Tree, _context: SchematicContext) => {
        const { name } = _options;
        tree.create('hello.js', `console.log('Hello ${name}');`);
        return tree;
      };
    }
    

    调试(每次调试前将上次生成的hello.js删除):

    $ npm run build
    $ schematics .:my-schematics Mirai --debug=false
    or
    $ schematics .:my-schematics --name=Mirai --debug=false
    or
    $ schematics .:my-schematics --debug=false 
    未传入name参数会提示: ? Who do we want to greet? 
    

    显示生成hello.js文件(CREATE hello.js (27 bytes)),内容:console.log('Hello Mirai');,参数传入成功!


    5. 生成更复杂的schematic模板

    创建一个新的模板component来体验类似ng g c <component-name>命令生成的<component-name>.component.ts文件。

    在根目录下调用schematics blank component,在生成/src/component/文件夹下创建files文件夹,并在里面创建__name@dasherize__.component.ts.template文件。(另外需要在/src/component/文件夹下创建schema.json schema.d.ts,在collection.json中添加schema属性等,见上一步)

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

    模板文件书写:

    • 模板语言使用 EJS
    • @angular-devkit/core 中引入 strings ,使用其中的 dasherize / classify / underscore 等方法对 name 进行处理。

    EJS标签含义:

    • <% '脚本' 标签,用于流程控制,无输出。
    • <%_ 删除其前面的空格符
    • <%= 输出数据到模板(输出是转义 HTML 标签)
    • <%- 输出非转义的数据到模板
    • <%# 注释标签,不执行、不输出内容
    • <%% 输出字符串 '<%'
    • %> 一般结束标签
    • -%> 删除紧随其后的换行符
    • _%> 将结束标签后面的空格符删除
    // index.ts
    import { Rule, SchematicContext, Tree, mergeWith, applyTemplates, apply, url } from '@angular-devkit/schematics';
    import { Schema } from './schema';
    import { strings } from '@angular-devkit/core';
    
    export function component(_options: Schema): Rule {
      return (tree: Tree, _context: SchematicContext) => {
        return mergeWith(apply(url('./files'), [
          applyTemplates({
            ...strings,
            name: _options.name
          })
        ]))(tree, _context);      //(tree, _context)防止TS编译器报警 "tree 未使用"
      };
    }
    

    修改index.ts中的转换规则:

    • url() 指定模板文件路径。
    • applyTemplate() 接受向模板文件嵌入的参数及处理函数,转换文件同时删去 .template 后缀。
    • apply() 对模板源应用多个规则,并返回转换后的模板。
    • @angular-devkit/schematics中引入以上方法。

    在当前工程根路径下执行:

    $ npm run build
    $ schematics .:component --name=UserList --debug=false
    

    成功生成user-list.component文件,可以看到,内容中name参数被修改为传入的UserList的对应格式。

    最后发布至NPM,就可以在项目中快速生成自定义的模板代码啦。

    总结

    以上是一个基本的模板生成例子,Schematics 运行在一个 Node 容器内,所以其可玩性非常强,可以操作文件并修改文件内容,绝大多数文件类型都可以找到相对应的现有类库来支持。

    参考@schematics/angular包,可以封装一些类似其utility下的公用方法,来指定生成文件的路径或验证所填参数等。


    参考

    Total Guide To Custom Angular Schematics

    Schematicsを作ってみよう

    angular-cli/packages/angular_devkit/schematics

    Use Angular Schematics to Simplify Your Life


    起源地下载网 » 使用 Angular Schematics 快速生成模板代码

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元