浅谈Angular Cli Schematics

写在前面

Schematics 是前端开发工作流工具,例如:创建一个组件、变更配置项至当前项目。并且不限制任何语言环境;虽然如此,但 Schematics 目前依然只能依赖 Angular Cli 来运行相应的命令行。

本文是在重构 ng-alain schematics 时阅读 @angular-devkit 源码的一些记录;而关于 Schematics 的运用在知乎上有好几篇不错的文章,我将尽可能跳开一些不必要的重复性工作,建议阅读本文时可以同下列文章一起阅读。

指令类型

Schematics 一共包含四个指令:

  • add 添加一个 Library 至项目
  • new 创建一个新 Angular 项目
  • generate 基于 Schematics 创建或修改文件
  • update 更新应用程序或依赖项

其实除了 add 会事先执行一次 npm i (取决于 angular.jsoncli/packageManager 配置值,默认:npm)指令以外,其他指令实际上都是基于 Schematics 创建或修改文件。

generate 指令会更纯粹,需要你手动指定 Schematic 名称,例如:ng g class <ClassName>。其他三个指令是对其进一步简化,像 ng add 实际相当于 ng g ng-add 这里的 ng-add 是固定名称,若你希望创建一个支持 ng add 那么你就必须有一个 ng-add 的 Schematic。

执行原理

Schematics 执行核心的本质就是在维护一个非常大的 Observable 数据流,这里的数据就是文件树。

核心的主轴是执行一个 Schematics 时会在开始时构建一个虚拟文件系统 virtual-fs 就像 Rxjs 的 Observable,后续的操作符都是对文件系统的变更动作,最后将虚拟文件系统的内容影射至物理文件中。

一个 Schematics 可以包含多个不同的指令,例如默认 Angular Schematics 有非常多我们熟悉的 modulecomponent 等,而管理这些指令是通过 collection.json 配置项。

Schematics 创建完虚拟文件系统环境后,紧跟着依 collection.json 构建 Collection 对象,再根据指令中的名称创建 Schematic 对象;并且调用并运行 Schematic Name 所对应目录名下 index.ts 文件,例如一个 Schematic 完整的代码结构:

function rule1() {
  return (host: Tree, context: SchematicContext) => {
      // doing
  };
}
export default function(options: ApplicationOptions): Rule {
  return (host: Tree, context: SchematicContext) => {
    return chain([ rule1(), rule1() ]);
  }
}

最终返回一个 Rule 类型,其本质是:

(tree: Tree, context: SchematicContext) => Tree | Observable<Tree> | Rule | void

若返回的是一个 Observable 类型时意味者这里的空间变得无限大:

function rule1() {
  return (host: Tree, context: SchematicContext) => {
      return of(host);
  };
}

比如构建自己的远程代码片断库。

任务器

Schematics 除了运行 Schematic 指令以外,还需要一些对项目进行额外操作,例如:安装Node依赖包、初始化 Git 等。其实运行 Schematic 指令本身也是一种任务。这些任务是通过 SchematicContext 进行管理。

例如我们希望在执行一个 Schematic 指令后调用一次 Node 依赖包的安装,只需要调用内置的 NodePackageInstallTask 任务:

(host: Tree, context: SchematicContext) => {
    context.addTask(new NodePackageInstallTask());
}

Angular.json

angular.json 与 Schematic 有着非常密切的关系,大多数需要通过 angular.json 配置信息来获取目录路径、默认配置项等信息。特别是当编写 Schematic 时总是需要考虑多项目的情况,因此绝大多数都需要依赖 angular.json 来确认具体项目名及路径信息。

每一个 Schematic 指令都有相应的参数信息,这些参数信息也可以直接被映射在 angular.json 上面并当成默认参数值:

{
  "schematics": {
    "ng-alain:list": {
      "spec": false
    },
    "@schematics/angular:component": {
      "spec": false
    }
  }
}

通过 ng g ng-alain:module <name>(或 ng g component <name>)生成时将忽略测试文件;当然对于这些默认参数的转化都是 Schematics 内自动完成。

总结

以上是一些简单总结,Schematics 可玩性非常强,它是运行在一个 Node 容器内,因此可以使用当下所有 Node 类库。

而 Schematics 的操作除了文件以外,也会对文件内容进行修改,这一些也很有意思。像 ts 文件可以利用 typescript 类库来获取或调整 ts 文件内容某个变量名或值。而 html 文件可以利用 parse5 来解析并修改,绝大多数文件类型都可以找到相对应的现有类库来支持。

Schematics 只是 @angular-devkit 中的一小部分而已,还包括:Architect 用于改变 Angular cli 的运行机制,虽然本质上是在改变 Webpack 配置文件,但谁叫 Webpack 有着无限可能呢。

原先 @angular-devkit 是作为一个独立的仓储位于 @angular/devkit,然而不久前被合并入 @angular-cli 里。

(完)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • Angular的6.0.0版本发布了!这个主要版本很少关注底层框架,更多关注工具链,以及怎样使它更容易快速适应An...
    RIA爱好者阅读 843评论 0 1
  • 1 Webpack 1.1 概念简介 1.1.1 WebPack是什么 1、一个打包工具 2、一个模块加载工具 3...
    Kevin_Junbaozi阅读 6,657评论 0 16
  • Angular 6 重点关注工具链以及工具链在 Angular 中的运行速度问题。这次更新还包括框架包(@angu...
    c88f3007e318阅读 1,299评论 0 2
  • 当年的的无脸男,现在想起来,还是感动到泪奔。 无助地坐在公交车上,听着抒情的音乐,一首又一首。 曾经的固执,曾经的...
    向布谷鸟说早安阅读 265评论 0 0