Brian F爱
从俄勒冈州波特兰的一位专注yobet英雄联盟于Angular、Web技术和Node.js的谷歌开发专家那里学习。
广告 ·ultimatecourses.com
用终极课程学习角度正确的方式

NG添加示意图

学习如何构建一个添加库的Angular原理图。

入门教程

如果你是Angular Schematics的新手,那么我建议你从我的角度原理图教程

Angularfire原理图

安装AngularFire简单:

  1. 使用NPM或YARN安装两个Firebase.@angular /火模块。
  2. 把你的Firebase项目的配置添加到Angular中环境文件。
  3. 将AngularFire模块导入根模块。

虽然这是一个简单的安装路径,但我认为解决所有这一切的原理图,它会很有趣,包括提示您的Firebase配置。

ng补充道

试试看:

$ ng new demo $光盘演示$ NG.添加角火原理图

演示

ng添加angular-fire-schematics

下载

目标

我的目标是让你们学到:

  • 如何创建一个将库添加到Angular项目(应用或库)中的原理图。
  • 使用TypeScript抽象语法树(AST)的开始。
  • 如何将文件更新提交到文件中的文件

我们的目标是建立可以使用Angular CLI添加的示意图。

创建原理图集合

如果您尚未安装原理图CLI,则通过NPM或YARN执行此操作:

$npm安装- g @angular-devkit / schematics-cli $添加-g @ Angular-devkit / schematics-cli

第一步是使用使用的创建新的原理图集合空白的示意图:

$ schicatics空白--name=角火原理图

这将创建一个新的角火原理图目录,添加必要的文件和文件夹以构建原理图,然后安装必要的依赖项。

让我们为我们的项目初始化一个Git仓库:

$光盘棱角 - 原理图数$git在里面

继续并在您喜欢的编辑器或IDE中打开项目。我将使用VS Code:

代码angular-fire-schematics美元

创建ng-add目录

让我们清理我们的SRC.目录真实快速:

$rm-RF SRC / Angular-Fire-Schematics $MKDIR.src / ng-add美元触碰src / ng-add / schema.json $触碰src / ng-add / index.ts

添加原理图到集合

打开src / collection.json.文件,并添加ng-add作品集示意图:

{“美元模式”“. . / node_modules / @angular-devkit /图表/ collection-schema.json”“图表”{“ng-add”{“描述”在不影响任何模板的情况下将Angular Firebase添加到应用中“工厂””。/ ng-add指数”“架构”“./ng-add/schema.json”“别名”[“安装”]}}}

我指定了以下属性:

  • 描述的示意图。
  • 工厂函数,它将作为原理图的“入口”点执行。在本例中,我从src / ng-add / index.js文件。
  • 架构的示意图。
  • 别名为我们的原理图声明别名的数组。这就是使用Angular CLI时使用速记“C”可以生成组件的原因。

注意,如果你不导出一个默认函数,你可以使用下面的语法,在这里我们在磅(#)符号后面指定要调用的函数:“工厂”:“./ng-add/index#functionname

定义原理图架构

接下来,定义ng-add原理图的模式。模式将包括新的x-prompt在v7中引入的属性。这将提示用户输入他们的Firebase配置。

创建一个新文件src / ng-add / schema.json

{“美元模式”“http://json-schema.org/schema”“id”“angular-firebase-schematic-ng-add”“标题”“Angular Firebase NG-Add原理图”“类型”“对象”“特性”{“项目”{“类型”“细绳”“描述”“这个项目的名字。”“$默认”{“$源”“项目名”}}“apikey”{“类型”“细绳”“默认”“描述”“你的Firebase API键”“x-xpert”“你的项目是什么?”}“authDomain”{“类型”“细绳”“默认”“描述”“你的Firebase域”“x-xpert”“你的项目的authDomain是什么?”}“databaseURL”{“类型”“细绳”“默认”“描述”"你的Firebase数据库URL"“x-xpert”“什么是你项目的databaseURL?”}“projectId”{“类型”“细绳”“默认”“描述”“你的Firebase项目ID”“x-xpert”“项目的id是什么?”}“storagebucket”{“类型”“细绳”“默认”“描述”“你的火基存储桶”“x-xpert”“你的项目的存储空间是什么?”}“messagingsenderid”{“类型”“细绳”“默认”“描述”“您的Firebase消息发送者ID”“x-xpert”“你的项目的消息人员是什么?”}}“必需的”[]“additionalProperties”错误的}

对于每个选项,我们指定:

  • 类型签字类型
  • 一种默认的价值。
  • 描述
  • x-prompt值,用于在命令行上未指定该选项时提示用户

定义架构

我喜欢强烈键入用户可以指定的选项。这为我提供了在使用时的类型安全性选项我原理图的进入函数的论证。

创建一个新的src / app / schema.ts文件和导出模式接口:

出口界面模式{/ ** Firebase API键。* /apikey.字符串;/ ** Firebase授权域名。* /Authdomain.字符串;/ ** Firebase DB URL。* /DataberUrl.字符串;/ **项目的名称为目标。* /项目字符串;/ ** Firebase项目ID。* /ProjectId.字符串;/ ** Firebase存储桶。* /存储空间字符串;/** Firebase消息发送者ID。* /messagingSenderId字符串;}

创建默认功能

脚手架脚手架的最后一步是创建我常用的内容作为“条目”函数。这是执行原理图时调用的函数。如果你记得,我们将我们指定了路径src / index.js.文件在collection.json文件。

将以下默认功能添加到src / ng-add / index.ts文件:

出口默认的功能选项模式规则{返回_语境示意图= >{返回;};}

构建和运行

虽然我们目前只是一个空的壳,让我们建立并运行原理图来验证到目前为止我们创建的内容:

$构建$ schematics .:ng-add

沙盒测试

虽然示意图应包括单位测试套件,以提供必要的覆盖,以便验证原理图的质量,我喜欢使用沙箱测试方法,视觉上差异为执行示意图所做的变化。

我从一个非常聪明的工程师同事Kevin Schuchard那里学到了这个技巧。看看他关于使用沙盒开发Angular示意图的文章

首先,使用ng新命令。我将为应用程序提供名称“sandbox”:

$ ng新的沙盒

为了避免在沙箱应用程序中嵌入git存储库,请删除.git.目录内沙箱目录中。然后,让我们创建一个新的提交与我们项目的所有更改。

$rm射频沙箱/。git美元git添加-  $gitcommit - m“初步提交”

然后,让我们在Angular的CLI中定义一些脚本来链接、清理和测试我们的原理图:

{“脚本”{“构建”“tsc - p tsconfig.json”“干净的”git checkout HEAD——sandbox && git clean -f -d sandbox“链接:示意图”“纱线链接&& CD沙箱&&纱线链接\”Angular-Fire-Schematics \“”“沙箱:ng-add”“CD沙箱&& ng v Angular-fire-schematics:ng-add”“测试”“纱线清洁&&纱线沙箱:NG-Add && Yarn测试:沙箱”“测试:单位”"yarn build && jasmine src/**/*_spec.js"“测试:沙箱”cd沙箱&&纱线棉绒&&纱线测试&&纱线制作}}

最后,链接角火原理图包到沙箱执行:

$链接:原理图

我们现在准备使用我们的沙箱应用程序中的角CLI构建和执行我们的原理图。

公用事业公司

我们将使用许多公用事业职能提供@angular /图表@angular / cdk模块。大多数功能都位于一个公用事业目录中。这些工具将使我们能够完成:

  • 更新项目包中的依赖项.json文件,
  • 安装依赖关系,
  • 决定Angular项目的工作区配置,
  • 更新角度模块,
  • 和更多。

让我们使用NPM或YARN安装两个模块:

$添加@angular /图表@angular / cdk $npm安装@ Angular / Schematics @ Angular / CDK

我还为此项目带来了几个实用程序功能。这些实用功能从各种来源收集,包括角CLI示意图,CDK原理图,角度材料原理图等。

复制以下文件角火原理图SRC / ill.目录:npmjs.tsproject-configurations.tsProject-Environment-File.ts版本-agnostic-typescript.ts

链规则

我们的第一批任务是构建NG-Add原理图,可以将AngularFire添加到角度项目,是将必要的依赖性添加到package.json.文件。

更新默认功能src / index.ts文件,以使用链()将函数链接在一起多种规则:

出口默认的功能选项模式规则{返回_语境示意图= >{返回[addPackageJsonDependenciesinstallDependenciessetupProject选项]_语境;};}

然后,声明addpackagejsondependencies()installdependencies()setupproject()功能:

功能addPackageJsonDependencies规则{}功能installDependencies规则{返回_语境示意图= >{返回;}}功能setupProject选项模式规则{安慰日志选项;返回_语境示意图= >{返回;}}

添加依赖项

接下来,我们将实现addpackagejsondependencies()功能src / index.ts文件:

进口{addPackageJsonDependencyNodeDependencyNodeDependencyType}“@schematics /角度/工具/依赖”;进口{getlatestnodeversion.NpmRegistryPackage}'../util/npmjs';功能addPackageJsonDependencies规则{返回_语境示意图可观测的<>= >{返回'firebase''@角/火'管道concatMap的名字= >getlatestnodeversion.的名字地图npmregistrypackage.NpmRegistryPackage= >{常量重点依赖NodeDependency={类型NodeDependencyType默认的名字npmregistrypackage.的名字版本npmregistrypackage.版本覆盖错误的};addPackageJsonDependency重点依赖;_语境日志记录器信息“✅️还说依赖;返回;};};}

让我们回顾一下:

  • 首先,addpackagejsondependencies()是一个返回a的工厂函数规则,接受示意图对象。
  • 我们创造一个新的可观测的使用的()发出两个通知的函数是字符串:'firebase'和'@角/火'。
  • 我用的是效用函数getlatestnodeversion()返回一个可观测的NpmRegistryPackage中的每个依赖项http://registry.npmjs.orgAPI。
  • 我们创造一个新的NodeDependency对象,然后调用addpackagejsondendency()函数。这些类型和函数是从中导入的@schematics /角模块并位于实用程序/附件目录中。
  • addpackagejsondendency()函数完成向包添加依赖项的繁重工作。json文件。
  • 最后,我们使用示意图注销一条提示依赖项已成功添加的信息语句。

然后,运行构建和测试脚本:

$建立美元测试

查看package.json文件的差异:

$git沙箱/包.JSON.

注意这两种@angular /火Firebase.依赖项已经添加到沙箱应用程序中package.json.文件。

NG-Add原理图添加包依赖项

安装依赖关系

使用我们的申请package.json.文件更新后,下一步就是安装新的依赖项。

实施installdependencies()如下:

进口{nodepackageinstalltast.}'@ Angular-devkit / schematics / tasks';功能installDependencies规则{返回_语境示意图= >{_语境addTask新的nodepackageinstalltast.;_语境日志记录器调试“✅️依赖安装的;返回;};}

值得庆幸的是,使用nodepackageinstalltast.从中出口的课程@angular-devkit /图表/任务模块。

让我们再次构建并运行原理图,我们应该看到我们的新依赖项在更新package.json.文件:

$建立美元测试

NG-Add原理图添加包依赖项

安装原理图

ng-addSchematic添加必要的依赖项并安装它们。下一步是创建一个原理图,为AngularFire执行必要的设置和配置。

打开src / collection.json.文件并定义一个标题的新示意图NG-Add-Setup-Project。完整文件现在应该如下所示:

{“美元模式”“. . / node_modules / @angular-devkit /图表/ collection-schema.json”“图表”{“ng-add”{“描述”在不影响任何模板的情况下将Angular Firebase添加到应用中“工厂””。/ ng-add指数”“架构”“./ng-add/schema.json”“别名”[“安装”]}“ng-add-setup-project”{“描述”"在安装ng-add依赖项后设置指定的项目。"“私人”真的“工厂”“./ng-add/setup-project”“架构”“./ng-add/schema.json”}}}

接下来,创建src / ng-add / setup-project.ts文件:

$触碰src / ng-add / setup-project.ts

首先,我们将把默认函数stub掉:

进口{规则示意图}“@angular-devkit /图表”;进口{模式}'./schema';出口默认的功能选项模式规则{返回_语境示意图= >{返回[addEnvironmentConfig选项importEnvironemntIntoRootModule选项addAngularFireModule选项]_语境;};}功能addEnvironmentConfig选项模式规则{返回_语境示意图= >{返回;};}功能addAngularFireModule选项模式规则{返回_语境示意图= >{返回;};}功能importEnvironemntIntoRootModule选项模式规则{返回_语境示意图= >{返回;};}

该计划是:

  1. 将配置信息添加到环境文件。
  2. 进口环境文件进入app.module.ts文件。
  3. 添加AngularFireModule.InitializeApp()方法进口阵列在@NgModule ()装饰的appmodule.类。

这似乎非常直接。

runschematictask.

在继续进行设置之前,我们需要运行新创建的NG-Add-Setup-Project原理图来自ng-add示意图。为了做到这一点,我们将使用runschematictask.类。

让我们完成实施setupproject()功能src / ng-add / index.ts文件:

功能setupProject选项模式规则{返回_语境示意图= >{常量installTaskId=_语境addTask新的nodepackageinstalltast.;_语境addTask新的runschematictask.“ng-add-setup-project”选项[installTaskId];返回;};}

回顾:

  • 在我们执行任务之前,我们需要等到以前的任务安装节点包依赖项已完成。要做到这一点,我们首先需要得到installTaskId这是我们的新任务所依赖的。
  • 接下来,我们调用addtask()对策示意图类指定新的runschematictask.然后是依赖任务标识符数组。
  • 请注意,运行另一个原理图时,我们会指定原理图名称以及原理图的选项。我们将传递用户指定的选项ng-add示意图。

更新环境

打开src / setup-project.ts文件化并实现AddEnvironmentConfig()功能:

功能addEnvironmentConfig选项模式规则{返回语境示意图= >{常量工作空间=getWorkspace.;常量项目=getProjectFromWorkspace工作空间选项项目;常量envPath=getProjectEnvironmentFile项目;/ /验证环境。ts文件存在如果!!envPath{返回语境日志记录器警告`❌无法找到环境文件:"$ {envPath}“。跳过Firebase配置。`;}//添加到环境中的firebase配置。ts文件常量插入=',\ n'+`重火力点:{\ n`+`apikey:'$ {选项apikey.}' \ n`+`Authdomain:'$ {选项Authdomain.}' \ n`+`atainisturl:'$ {选项DataberUrl.}' \ n`+`ProjectID:'$ {选项ProjectId.}' \ n`+`storageBucket:“$ {选项存储空间}' \ n`+`messagingSenderId:“$ {选项messagingSenderId}' \ n`+`}`;常量源文件=readIntoSourceFileenvPath;//验证Firebase Config尚不存在常量sourcefiletext.=源文件getText;如果sourcefiletext.包括插入{返回;}//从SourceFile获取AST中的顶级节点对象的数组常量节点=getsourcenodes.源文件作为任何;常量开始=节点节点= >节点种类===.tssyntaxkind.openbracetoken.!!;常量结尾=节点节点= >节点种类===.tssyntaxkind.Frestfbracetoken.开始结尾!!;常量录音机=beginUpdateenvPath;录音机insertLeft结尾pos插入;commitupdate.录音机;语境日志记录器信息'✅️环境配置';返回;};}

这是相当长的时间!

就让我们一探究竟吧:

  • 控件提供的一些实用函数@schematics /角模块,位于公用事业目录中。
  • 首先,我们得到了WorkspaceSchema使用getWorkspace ()函数。这包含Angular工作空间的元数据(在Angular Version 6中引入)。
  • 接下来我们得到了WorkspaceProject.使用getProjectFromWorkspace()函数。它包含了Angular项目的元数据(lib或app),包括:根目录、默认组件前缀等。
  • 然后我们得到了这个项目的道路环境文件。我们需要知道这一点以更新文件。
  • 接下来我们建立插入细绳。这包含用户输入的Firebase配置数据。
  • readIntoSourceFile ()功能很重要,我们接下来会详细介绍它。它返回TypeScript文件的顶级抽象语法树(AST)节点。
  • 属性中还需要验证firebase配置是否已经存在环境文件。我们将简单地使用getText()方法,然后确定插入文本是否已存在。这有点脆,可以使用一些硬化来确保尚不存在Firebase配置。
  • 使用getSourceNodes ()实用程序功能我们可以检索一个数组节点对象内源文件AST。
  • 我们将使用它array.prototype.find()找到的方法节点那是一个openbracetoken.。请记住,环境文件包含单个环境导出的常量对象。我们将找到启动环境配置对象的左大括号({)节点。
  • 我们也会找到结束节点这是关闭支撑(})。
  • 使用tree.beginUpdate ()方法,我们可以开始记录对树中指定文件的更改。
  • 我们将插入插入在结束时开始的文字环境目的。
  • 最后,我们注销一些信息,说明环境配置步骤已经成功完成。

什么是AST?

在进一步讨论之前,让我们快速回顾一下什么是抽象语法树(AST)。

根据维基百科

在计算机科学中,抽象语法树(AST),或者仅仅是语法树,是用编程语言编写的源代码的抽象语法结构的树表示。树的每个节点表示源代码中出现的一个构造。

如您所能猜测Ringscript提供了一个声明文件lib / typescript.d.ts.它包含TypeScript抽象语法树的所有类型定义。

为什么这是重要的?

使用AST,我们可以使用可靠的编程接口来修改TypeScript源文件。

访问这一点源文件

一种源文件是顶级节点对于Questcript AST。这是与AST一起使用的起点。我们将使用它createSourcefile()通过类型签字提供的方法来访问源文件

功能readIntoSourceFile主持人文件名字符串源文件{常量缓冲=主持人文件名;如果缓冲===.空值{新的示意图Xpeption.`文件$ {文件名}不存在。`;}返回tscreateSourcefile.文件名缓冲toString.“utf - 8”tsscripttarget.最新的真的;}

首先,我们使用读()对策要获取该文件缓冲。然后,我们调动createSourcefile()方法,提供文件路径和TypeScript文件的内容。

进口环境

回到为AngularFire创建ng-add原理图的任务,我们的原理图的下一步是实现importenvironmontintorootmodule()函数。此功能负责导入环境恒定对象进入根目录appmodule.使用标准的es6导入语法。

正如我们之前所做的那样,我们将使用由提供的一些实用程序函数提供@schematics /角模块。

打开src / setup-project.ts和实现importenvironmontintorootmodule()功能:

功能importEnvironemntIntoRootModule选项模式规则{返回语境示意图= >{常量IMPORT_IDENTIFIER='环境';常量工作空间=getWorkspace.;常量项目=getProjectFromWorkspace工作空间选项项目;常量AppModulepath.=getAppModulepath.getProjectMainFile项目;常量envPath=getProjectEnvironmentFile项目;常量源文件=readIntoSourceFileAppModulepath.;如果Isimported.源文件作为任何IMPORT_IDENTIFIERenvPath{语境日志记录器信息'✅️环境已经被导入到根模块中';返回;}常量改变=IslessImport.源文件作为任何AppModulepath.IMPORT_IDENTIFIERenvPath取代/ \\.TS$ /''作为insertchange.;常量录音机=beginUpdateAppModulepath.;录音机insertLeft改变pos改变toAdd;commitupdate.录音机;语境日志记录器信息'✅️导入环境到根模块';返回;};}

就让我们一探究竟吧:

  • 我们将使用一些熟悉的函数来获取我们正在其中执行原理图的工作空间和项目的信息。
  • getAppModulePath()对象的路径字符串app.module.tsAngular项目中的文件(lib或app)。
  • 使用环境文件和根应用程序模块的信息,我们就可以将es6 import语句插入到app.module.ts文件。
  • 我们首先验证环境标识符尚未导入到模块中。如果是,那我们就结束了。
  • 否则,我们需要插入导入。我们将使用它Insterimport()导出的函数。@angular /图表模块要创建一个新的insertchange.目的。
  • 使用改变我们使用的对象启动并提交更新到应用程序模块文件updateRecOrder.

导入模块

最后一步是更新@NgModule ()装饰的appmodule.导入Firebase模块。

开放src / setup-project.ts和实现addAngularFireModule ()功能:

功能addAngularFireModule选项模式规则{返回语境示意图= >{常量MODULE_NAME='AngularFireModule.InitializeApp(环境.Firebase)';常量工作空间=getWorkspace.;常量项目=getProjectFromWorkspace工作空间选项项目;常量AppModulepath.=getAppModulepath.getProjectMainFile项目;//验证模块没有被导入如果hasngmoduleimport.AppModulepath.MODULE_NAME{返回安慰警告红色的`无法导入”$ {大胆的MODULE_NAME}“ 因为 ”$ {大胆的MODULE_NAME}“已经进口了。`;}//将ngmodule添加到root ngmodule导入addmoduleimporttorootmodule.MODULE_NAME'@角/火'项目;语境日志记录器信息'✅️将AngularFireModule进入根模块';返回;};}

让我们回顾一下:

  • 再次,您将注意到,我们正在使用多个实用程序函数来访问工作区和项目的元数据,然后使用此,我们得到的路径app.module.ts文件。
  • 首先,我们验证模块是否未使用alredy使用hasngmoduleimport()函数。这个是我从@angular / cdk模块,位于原理图/ Utils / AST目录中。
  • 然后我们援引addModuleImportToRootModule ()函数将Firebase模块导入添加到@NgModule ()装饰师进口大批。

结论

我希望这篇文章能够对那些有兴趣学习如何为自己的项目或组织构建原理图,或者为Angular社区做出贡献的人有所帮助。

我在几个聚会上提出了建筑角度的原理图,我被提出的一个常见问题是:

“你怎么知道在哪里找到这些实用程序功能?”

通过研究这一点角征角度的材料角CDK.示意图我了解了这些团队使用的许多实用程序函数来构建原理图。我建议您查看这些原理图的源代码,以帮助您了解如何构建原理图并发现它们提供和使用的许多实用程序功能。

Brian F爱

嗨,我是布莱恩。我对TypeScript, Angular和Node.js感兴趣。我和我最好的朋友邦妮结婚了,我住在波特兰,我经常滑雪。