SlideShare a Scribd company logo
Use Angular Schematics to Simplify Your Life
November 7, 2019
Matt Raible | @mraible
Photo by Trish McGinity mcginityphoto.com
Blogger on raibledesigns.com and

developer.okta.com/blog
Web Developer and Java Champion
Father, Husband, Skier, Mountain
Biker, Whitewater Rafter
Open Source Connoisseur
Hi, I’m Matt Raible!
Bus Lover
Okta Developer Advocate
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
developer.okta.com
Agenda
1. What are Angular Schematics?
2. Create and Test a Schematic
3. Schematic Templates
4. Template Expression Language
5. OpenID Connect Authentication
6. Schematics for React, Vue, and Ionic
What are Angular Schematics?
Create a Schematic
$ npm i -g @angular-devkit/schematics-cli
$ schematics blank —-name=my-component
CREATE /my-component/README.md (639 bytes)
CREATE /my-component/.gitignore (191 bytes)
CREATE /my-component/.npmignore (64 bytes)
CREATE /my-component/package.json (539 bytes)
CREATE /my-component/tsconfig.json (656 bytes)
CREATE /my-component/src/collection.json (231 bytes)
CREATE /my-component/src/my-component/index.ts (318 bytes)
CREATE /my-component/src/my-component/index_spec.ts (474 bytes)
Project metadata: collection.json
{
"$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"my-component": {
"description": "A blank schematic.",
"factory": "./my-component/index#myComponent"
}
}
Factory function: index.ts
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
export function myComponent(_options: any): Rule {
return (tree: Tree, _context: SchematicContext) => {
return tree;
};
}
Unit test: index_spec.ts
import { Tree } from '@angular-devkit/schematics';
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
import * as path from 'path';
const collectionPath = path.join(__dirname, '../collection.json');
describe('my-component', () => {
it('works', () => {
const runner = new SchematicTestRunner('schematics', collectionPath);
const tree = runner.runSchematic('my-component', {}, Tree.empty());
expect(tree.files).toEqual([]);
});
});
Schematic Templates
Copy and Manipulate Templates: directory structure
$ tree .
src/my-component/
├── files
│ └── src
│ └── app
│ ├── app.component.html
│ └── app.component.ts
├── index.ts
└── index_spec.ts
Copy and Manipulate Templates: app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = '<%= name %>';
}
src/my-component/files/src/app/app.component.ts
Copy and Manipulate Templates: app.component.html
src/my-component/files/src/app/app.component.html
<div style="text-align:center">
<h1>
Hello, {{ name }}
</h1>
</div>
<router-outlet></router-outlet>
Copy and Manipulate Templates: schema.json
{
"$schema": "http://json-schema.org/schema",
"id": "SchematicsMyComponent",
"title": "My Component Schema",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Your Name",
"x-prompt": "What is your name?"
}
},
"required": ["name"]
}
Copy and Manipulate Templates: collection.json
{
"$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"my-component": {
"description": "A blank schematic.",
"factory": "./my-component/index#myComponent",
"schema": "./my-component/schema.json"
}
}
}
Copy and Manipulate Templates: index.ts
export function myComponent(_options: any): Rule {
return (tree: Tree, _context: SchematicContext) => {
setupOptions(tree, _options);
const movePath = normalize(_options.path + '/');
const templateSource = apply(url('./files/src'), [
template({..._options}),
move(movePath),
// fix for https://github.com/angular/angular-cli/issues/11337
forEach((fileEntry: FileEntry) => {
if (tree.exists(fileEntry.path)) {
tree.overwrite(fileEntry.path, fileEntry.content);
}
return fileEntry;
}),
]);
const rule = mergeWith(templateSource, MergeStrategy.Overwrite);
return rule(tree, _context);
};
}
Copy and Manipulate Templates: setupOptions()
export function setupOptions(host: Tree, options: any): Tree {
const workspace = getWorkspace(host);
if (!options.project) {
options.project = Object.keys(workspace.projects)[0];
}
const project = workspace.projects[options.project];
options.path = join(normalize(project.root), 'src');
return host;
}
Copy and Manipulate Templates: index_spec.ts
beforeEach(() => {
appTree = schematicRunner.runExternalSchematic(
'@schematics/angular', 'workspace', workspaceOptions);
appTree = schematicRunner.runExternalSchematic(
'@schematics/angular', 'application', appOptions, appTree);
});
it('works', () => {
const runner = new SchematicTestRunner('schematics', collectionPath);
runner.runSchematicAsync(
'my-component', schemaOptions, appTree).toPromise().then(tree => {
const appComponent = tree.readContent(
‘/projects/schematest/src/app/app.component.ts');
expect(appComponent).toContain(`name = '${schemaOptions.name}'`);
});
});
Run Your Schematic with Angular CLI
$ npm pack
$ ng new my-test-app --routing --style css
$ cd my-test-app
$ npm install ../my-component/my-component-0.0.0.tgz
$ ng g my-component:my-component
Publish Your Schematic to npm
22
By default, .npmignore ignores all TypeScript files
Modify .npmignore so it doesn't exclude your template files!
Run npm publish
Add Support for ng add with Angular CLI
23
{
"$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"my-component": {
"description": "A blank schematic.",
"factory": "./my-component/index#myComponent",
"schema": "./my-component/schema.json"
},
"ng-add": {
"factory": "./ng-add/index",
"description": "Add schematic",
"schema": "./my-component/schema.json"
}
}
}
Add Support for ng add with Angular CLI
24
import { chain, Rule, schematic, SchematicContext, Tree, }
from '@angular-devkit/schematics';
export default function (options: any): Rule {
return (host: Tree, context: SchematicContext) => {
return chain([
schematic('my-component', options)
])(host, context);
};
}
Template Expression Language
Placeholder Description
<%= expression %>
Replaced with the result of the call of the given expression. This only supports
direct expressions, no structural (for/if/...) JavaScript.
<%- expression %>
Same as above, but the value of the result will be escaped for HTML when
inserted (i.e. replacing '<' with '<')
<% inline code %>
Inserts the given code into the template structure, allowing to insert structural
JavaScript.
<%# text %> A comment, which gets entirely dropped.
https://www.npmjs.com/package/@angular-devkit/schematics#content-templating
Example Template Code
import { Injectable } from '@angular/core';
<% if (platform === 'cordova') { %>
import { CordovaBrowser } from 'ionic-appauth/lib/cordova';
<% } else { %>
import { CapacitorBrowser } from 'ionic-appauth/lib/capacitor';
<% } %>
@Injectable({
providedIn: 'root'
})
export class BrowserService extends
<%= (platform === 'cordova') ? 'CordovaBrowser' : 'CapacitorBrowser' %> {
}
Secure Your Angular App in Minutes!
$ ng new my-secure-app --routing
$ cd my-secure-app
// create a SPA app on Okta, copy settings
$ ng add @oktadev/schematics
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
git clone https://github.com/oktadeveloper/okta-spring-webflux-react-
example.git
Blog, Screencast, and Source Code
https://developer.okta.com/blog/2019/02/13/angular-schematics
Supports Angular, React, Vue, Ionic 4, and React Native
Detects JavaScript or TypeScript
https://github.com/oktadeveloper/schematics
OktaDev Schematics
31
📱
Thanks!
Keep in Touch
raibledesigns.com
@mraible
Presentations
speakerdeck.com/mraible
Code
github.com/oktadeveloper
developer.okta.com
developer.okta.com

More Related Content

What's hot (20)

PDF
Spark IT 2011 - Developing RESTful Web services with JAX-RS
Arun Gupta
 
PDF
JAX-RS JavaOne Hyderabad, India 2011
Shreedhar Ganapathy
 
PDF
Spark IT 2011 - Java EE 6 Workshop
Arun Gupta
 
PDF
Spring Boot APIs and Angular Apps: Get Hip with JHipster! KCDC 2019
Matt Raible
 
PPT
Choosing a Java Web Framework
Will Iverson
 
PDF
Seven Simple Reasons to Use AppFuse
Matt Raible
 
PDF
Comparing JVM Web Frameworks - Rich Web Experience 2010
Matt Raible
 
PDF
Mobile Development with Ionic, React Native, and JHipster - ACGNJ Java Users ...
Matt Raible
 
PDF
Mobile Development with Ionic, React Native, and JHipster - AllTheTalks 2020
Matt Raible
 
PDF
How to Win at UI Development in the World of Microservices - THAT Conference ...
Matt Raible
 
PDF
Front End Development for Back End Java Developers - NYJavaSIG 2019
Matt Raible
 
PDF
Front End Development for Back End Java Developers - Jfokus 2020
Matt Raible
 
PDF
What's New in Spring 3.1
Matt Raible
 
PDF
Java Web Application Security - UberConf 2011
Matt Raible
 
PDF
Front End Development for Back End Developers - vJUG24 2017
Matt Raible
 
PDF
Web App Security for Java Developers - UberConf 2021
Matt Raible
 
PDF
Apache Roller, Acegi Security and Single Sign-on
Matt Raible
 
PDF
Bootiful Development with Spring Boot and React - SpringOne 2017
Matt Raible
 
PDF
JavaOne India 2011 - Running your Java EE 6 Apps in the Cloud
Arun Gupta
 
PDF
Case Study: Migrating Hyperic from EJB to Spring from JBoss to Apache Tomcat
VMware Hyperic
 
Spark IT 2011 - Developing RESTful Web services with JAX-RS
Arun Gupta
 
JAX-RS JavaOne Hyderabad, India 2011
Shreedhar Ganapathy
 
Spark IT 2011 - Java EE 6 Workshop
Arun Gupta
 
Spring Boot APIs and Angular Apps: Get Hip with JHipster! KCDC 2019
Matt Raible
 
Choosing a Java Web Framework
Will Iverson
 
Seven Simple Reasons to Use AppFuse
Matt Raible
 
Comparing JVM Web Frameworks - Rich Web Experience 2010
Matt Raible
 
Mobile Development with Ionic, React Native, and JHipster - ACGNJ Java Users ...
Matt Raible
 
Mobile Development with Ionic, React Native, and JHipster - AllTheTalks 2020
Matt Raible
 
How to Win at UI Development in the World of Microservices - THAT Conference ...
Matt Raible
 
Front End Development for Back End Java Developers - NYJavaSIG 2019
Matt Raible
 
Front End Development for Back End Java Developers - Jfokus 2020
Matt Raible
 
What's New in Spring 3.1
Matt Raible
 
Java Web Application Security - UberConf 2011
Matt Raible
 
Front End Development for Back End Developers - vJUG24 2017
Matt Raible
 
Web App Security for Java Developers - UberConf 2021
Matt Raible
 
Apache Roller, Acegi Security and Single Sign-on
Matt Raible
 
Bootiful Development with Spring Boot and React - SpringOne 2017
Matt Raible
 
JavaOne India 2011 - Running your Java EE 6 Apps in the Cloud
Arun Gupta
 
Case Study: Migrating Hyperic from EJB to Spring from JBoss to Apache Tomcat
VMware Hyperic
 

Similar to A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019 (20)

PDF
Front End Development for Back End Developers - UberConf 2017
Matt Raible
 
PDF
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Fwdays
 
PDF
Angular 2 for Java Developers
Yakov Fain
 
PPTX
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Codemotion
 
PPT
AngularJS Mobile Warsaw 20-10-2014
Dariusz Kalbarczyk
 
PPTX
Practical AngularJS
Wei Ru
 
PPTX
Angular Js Get Started - Complete Course
EPAM Systems
 
PPTX
AngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
Learnimtactics
 
PDF
using Mithril.js + postgREST to build and consume API's
Antônio Roberto Silva
 
PDF
Angular 2 Essential Training
Patrick Schroeder
 
PDF
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
Igor Bronovskyy
 
PDF
Angular server side rendering - Strategies & Technics
Eliran Eliassy
 
PDF
Voorhoede - Front-end architecture
Jasper Moelker
 
PDF
Exploring Angular 2 - Episode 1
Ahmed Moawad
 
PPTX
Angular - Beginner
Riccardo Masetti
 
PPTX
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
murtazahaveliwala
 
PDF
Building and deploying React applications
Astrails
 
PDF
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
OdessaJS Conf
 
PPT
Building Single Page Application (SPA) with Symfony2 and AngularJS
Antonio Peric-Mazar
 
PDF
How to Implement Micro Frontend Architecture using Angular Framework
RapidValue
 
Front End Development for Back End Developers - UberConf 2017
Matt Raible
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Fwdays
 
Angular 2 for Java Developers
Yakov Fain
 
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Codemotion
 
AngularJS Mobile Warsaw 20-10-2014
Dariusz Kalbarczyk
 
Practical AngularJS
Wei Ru
 
Angular Js Get Started - Complete Course
EPAM Systems
 
AngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
Learnimtactics
 
using Mithril.js + postgREST to build and consume API's
Antônio Roberto Silva
 
Angular 2 Essential Training
Patrick Schroeder
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
Igor Bronovskyy
 
Angular server side rendering - Strategies & Technics
Eliran Eliassy
 
Voorhoede - Front-end architecture
Jasper Moelker
 
Exploring Angular 2 - Episode 1
Ahmed Moawad
 
Angular - Beginner
Riccardo Masetti
 
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
murtazahaveliwala
 
Building and deploying React applications
Astrails
 
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
OdessaJS Conf
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Antonio Peric-Mazar
 
How to Implement Micro Frontend Architecture using Angular Framework
RapidValue
 
Ad

More from Matt Raible (20)

PDF
Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022
Matt Raible
 
PDF
Micro Frontends for Java Microservices - Belfast JUG 2022
Matt Raible
 
PDF
Micro Frontends for Java Microservices - Dublin JUG 2022
Matt Raible
 
PDF
Micro Frontends for Java Microservices - Cork JUG 2022
Matt Raible
 
PDF
Comparing Native Java REST API Frameworks - Seattle JUG 2022
Matt Raible
 
PDF
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
Matt Raible
 
PDF
Comparing Native Java REST API Frameworks - Devoxx France 2022
Matt Raible
 
PDF
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...
Matt Raible
 
PDF
Native Java with Spring Boot and JHipster - Garden State JUG 2021
Matt Raible
 
PDF
Web App Security for Java Developers - PWX 2021
Matt Raible
 
PDF
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...
Matt Raible
 
PDF
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...
Matt Raible
 
PDF
Java REST API Framework Comparison - UberConf 2021
Matt Raible
 
PDF
Native Java with Spring Boot and JHipster - SF JUG 2021
Matt Raible
 
PDF
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...
Matt Raible
 
PDF
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
Matt Raible
 
PDF
Get Hip with JHipster - Colorado Springs Open Source User Group 2021
Matt Raible
 
PDF
JHipster and Okta - JHipster Virtual Meetup December 2020
Matt Raible
 
PDF
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Matt Raible
 
PDF
Security Patterns for Microservice Architectures - SpringOne 2020
Matt Raible
 
Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022
Matt Raible
 
Micro Frontends for Java Microservices - Belfast JUG 2022
Matt Raible
 
Micro Frontends for Java Microservices - Dublin JUG 2022
Matt Raible
 
Micro Frontends for Java Microservices - Cork JUG 2022
Matt Raible
 
Comparing Native Java REST API Frameworks - Seattle JUG 2022
Matt Raible
 
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
Matt Raible
 
Comparing Native Java REST API Frameworks - Devoxx France 2022
Matt Raible
 
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...
Matt Raible
 
Native Java with Spring Boot and JHipster - Garden State JUG 2021
Matt Raible
 
Web App Security for Java Developers - PWX 2021
Matt Raible
 
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...
Matt Raible
 
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...
Matt Raible
 
Java REST API Framework Comparison - UberConf 2021
Matt Raible
 
Native Java with Spring Boot and JHipster - SF JUG 2021
Matt Raible
 
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...
Matt Raible
 
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
Matt Raible
 
Get Hip with JHipster - Colorado Springs Open Source User Group 2021
Matt Raible
 
JHipster and Okta - JHipster Virtual Meetup December 2020
Matt Raible
 
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Matt Raible
 
Security Patterns for Microservice Architectures - SpringOne 2020
Matt Raible
 
Ad

Recently uploaded (20)

PDF
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
PPTX
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PPTX
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 
PDF
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 
PPTX
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PDF
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
PPTX
Foundations of Marketo Engage - Powering Campaigns with Marketo Personalization
bbedford2
 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
PDF
Adobe Premiere Pro Crack / Full Version / Free Download
hashhshs786
 
PPTX
Coefficient of Variance in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
PDF
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
PPTX
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
PDF
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
PDF
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PPTX
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
PPTX
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
Foundations of Marketo Engage - Powering Campaigns with Marketo Personalization
bbedford2
 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
Adobe Premiere Pro Crack / Full Version / Free Download
hashhshs786
 
Coefficient of Variance in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 

A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019

  • 1. Use Angular Schematics to Simplify Your Life November 7, 2019 Matt Raible | @mraible Photo by Trish McGinity mcginityphoto.com
  • 2. Blogger on raibledesigns.com and developer.okta.com/blog Web Developer and Java Champion Father, Husband, Skier, Mountain Biker, Whitewater Rafter Open Source Connoisseur Hi, I’m Matt Raible! Bus Lover Okta Developer Advocate
  • 6. Agenda 1. What are Angular Schematics? 2. Create and Test a Schematic 3. Schematic Templates 4. Template Expression Language 5. OpenID Connect Authentication 6. Schematics for React, Vue, and Ionic
  • 7. What are Angular Schematics?
  • 8. Create a Schematic $ npm i -g @angular-devkit/schematics-cli $ schematics blank —-name=my-component CREATE /my-component/README.md (639 bytes) CREATE /my-component/.gitignore (191 bytes) CREATE /my-component/.npmignore (64 bytes) CREATE /my-component/package.json (539 bytes) CREATE /my-component/tsconfig.json (656 bytes) CREATE /my-component/src/collection.json (231 bytes) CREATE /my-component/src/my-component/index.ts (318 bytes) CREATE /my-component/src/my-component/index_spec.ts (474 bytes)
  • 9. Project metadata: collection.json { "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { "my-component": { "description": "A blank schematic.", "factory": "./my-component/index#myComponent" } }
  • 10. Factory function: index.ts import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; export function myComponent(_options: any): Rule { return (tree: Tree, _context: SchematicContext) => { return tree; }; }
  • 11. Unit test: index_spec.ts import { Tree } from '@angular-devkit/schematics'; import { SchematicTestRunner } from '@angular-devkit/schematics/testing'; import * as path from 'path'; const collectionPath = path.join(__dirname, '../collection.json'); describe('my-component', () => { it('works', () => { const runner = new SchematicTestRunner('schematics', collectionPath); const tree = runner.runSchematic('my-component', {}, Tree.empty()); expect(tree.files).toEqual([]); }); });
  • 13. Copy and Manipulate Templates: directory structure $ tree . src/my-component/ ├── files │ └── src │ └── app │ ├── app.component.html │ └── app.component.ts ├── index.ts └── index_spec.ts
  • 14. Copy and Manipulate Templates: app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { name = '<%= name %>'; } src/my-component/files/src/app/app.component.ts
  • 15. Copy and Manipulate Templates: app.component.html src/my-component/files/src/app/app.component.html <div style="text-align:center"> <h1> Hello, {{ name }} </h1> </div> <router-outlet></router-outlet>
  • 16. Copy and Manipulate Templates: schema.json { "$schema": "http://json-schema.org/schema", "id": "SchematicsMyComponent", "title": "My Component Schema", "type": "object", "properties": { "name": { "type": "string", "description": "Your Name", "x-prompt": "What is your name?" } }, "required": ["name"] }
  • 17. Copy and Manipulate Templates: collection.json { "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { "my-component": { "description": "A blank schematic.", "factory": "./my-component/index#myComponent", "schema": "./my-component/schema.json" } } }
  • 18. Copy and Manipulate Templates: index.ts export function myComponent(_options: any): Rule { return (tree: Tree, _context: SchematicContext) => { setupOptions(tree, _options); const movePath = normalize(_options.path + '/'); const templateSource = apply(url('./files/src'), [ template({..._options}), move(movePath), // fix for https://github.com/angular/angular-cli/issues/11337 forEach((fileEntry: FileEntry) => { if (tree.exists(fileEntry.path)) { tree.overwrite(fileEntry.path, fileEntry.content); } return fileEntry; }), ]); const rule = mergeWith(templateSource, MergeStrategy.Overwrite); return rule(tree, _context); }; }
  • 19. Copy and Manipulate Templates: setupOptions() export function setupOptions(host: Tree, options: any): Tree { const workspace = getWorkspace(host); if (!options.project) { options.project = Object.keys(workspace.projects)[0]; } const project = workspace.projects[options.project]; options.path = join(normalize(project.root), 'src'); return host; }
  • 20. Copy and Manipulate Templates: index_spec.ts beforeEach(() => { appTree = schematicRunner.runExternalSchematic( '@schematics/angular', 'workspace', workspaceOptions); appTree = schematicRunner.runExternalSchematic( '@schematics/angular', 'application', appOptions, appTree); }); it('works', () => { const runner = new SchematicTestRunner('schematics', collectionPath); runner.runSchematicAsync( 'my-component', schemaOptions, appTree).toPromise().then(tree => { const appComponent = tree.readContent( ‘/projects/schematest/src/app/app.component.ts'); expect(appComponent).toContain(`name = '${schemaOptions.name}'`); }); });
  • 21. Run Your Schematic with Angular CLI $ npm pack $ ng new my-test-app --routing --style css $ cd my-test-app $ npm install ../my-component/my-component-0.0.0.tgz $ ng g my-component:my-component
  • 22. Publish Your Schematic to npm 22 By default, .npmignore ignores all TypeScript files Modify .npmignore so it doesn't exclude your template files! Run npm publish
  • 23. Add Support for ng add with Angular CLI 23 { "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { "my-component": { "description": "A blank schematic.", "factory": "./my-component/index#myComponent", "schema": "./my-component/schema.json" }, "ng-add": { "factory": "./ng-add/index", "description": "Add schematic", "schema": "./my-component/schema.json" } } }
  • 24. Add Support for ng add with Angular CLI 24 import { chain, Rule, schematic, SchematicContext, Tree, } from '@angular-devkit/schematics'; export default function (options: any): Rule { return (host: Tree, context: SchematicContext) => { return chain([ schematic('my-component', options) ])(host, context); }; }
  • 25. Template Expression Language Placeholder Description <%= expression %> Replaced with the result of the call of the given expression. This only supports direct expressions, no structural (for/if/...) JavaScript. <%- expression %> Same as above, but the value of the result will be escaped for HTML when inserted (i.e. replacing '<' with '<') <% inline code %> Inserts the given code into the template structure, allowing to insert structural JavaScript. <%# text %> A comment, which gets entirely dropped. https://www.npmjs.com/package/@angular-devkit/schematics#content-templating
  • 26. Example Template Code import { Injectable } from '@angular/core'; <% if (platform === 'cordova') { %> import { CordovaBrowser } from 'ionic-appauth/lib/cordova'; <% } else { %> import { CapacitorBrowser } from 'ionic-appauth/lib/capacitor'; <% } %> @Injectable({ providedIn: 'root' }) export class BrowserService extends <%= (platform === 'cordova') ? 'CordovaBrowser' : 'CapacitorBrowser' %> { }
  • 27. Secure Your Angular App in Minutes! $ ng new my-secure-app --routing $ cd my-secure-app // create a SPA app on Okta, copy settings $ ng add @oktadev/schematics
  • 30. git clone https://github.com/oktadeveloper/okta-spring-webflux-react- example.git Blog, Screencast, and Source Code https://developer.okta.com/blog/2019/02/13/angular-schematics
  • 31. Supports Angular, React, Vue, Ionic 4, and React Native Detects JavaScript or TypeScript https://github.com/oktadeveloper/schematics OktaDev Schematics 31 📱