The Future of the Ionic CLI

The Ionic CLI should be your go to tool for building and maintaining Ionic applications.

It should provide:

A standardised project structure; code scaffolding; aliases; environment specific configuration; themes; logging; unit and e2e testing; and baked in best practices that have been discovered by the community over time.

Schematics

One of the major projects that the Angular team delivered in the last few months is Schematics.

To quote the Schematics README.md:

Schematics are generators that transform an existing file system. It can create files, refactor existing files, or move files around.

What distinguishes Schematics from other generators (like Yeoman and Yarn Create) is that schematics are purely descriptive; no changes are applied to the actual file system until everything is ready to be committed. There are no side effects, by design, in Schematics.

Let's install Schematics globally using npm:

npm install -g @angular-devkit/core
npm install -g @angular-devkit/schematics
npm install -g @schematics/schematics
npm install -g rxjs

Create a scaffold

We'll use @angular-devkit/schematics (the 'Schematics CLI') to create the scaffolding for a new project:

schematics @schematics/schematics:schematic --name ionic-angular-schematics

Note: The parameter @schematics/schematics:schematic consists of two parts. The first part @schematics/schematics is the name of the npm package we want to use. The second part schematic is the name of the Schematic we want to use to generate our scaffolding.

The directory structure and placeholders for the project:

├── /ionic-angular-schematics
    └── /node_modules
    └── /src
        └── /my-full-schematic   - A sample schematics
        └── /my-other-schematic  - A sample schematics
        └── /my-schematic        - A sample schematics
        ├── collection.json
    ├── package.json
    ├── tsconfig.json

Schematics is not done yet

Schematics was delivered in the last few months and is not done yet. So let's jump ahead and see if everything works as expected. We'll start by adding a copy of the default collection to our project.

The project's updated directory structure:

├── /ionic-angular-schematics
    └── /angular
        └── /app-shell
        └── /application
        └── /class
        └── /component
        └── /directive
        └── /enum
        └── /guard
        └── /interface
        └── /module
        └── /pipe
        └── /service
        └── /universal
        └── /utility
        ├── collection.json
    └── /node_modules
    └── /src
        ...
    ├── package.json
    ├── tsconfig.json

package.json

We need to update it as follows:

...

"schematics": "./angular/collection.json",

...

Publish our Project

Now we can publish our project:

npm publish --access=public

@ionic-angular/schematics

We'll install @ionic-angular/schematics globally using npm:

npm install -g @ionic-angular/schematics

You should see output like:

+ @ionic-angular/schematics@0.0.3
added 1 package in 3.369s

Create a scaffold

Let's use @ionic-angular/schematics to create the scaffolding for a new project:

ng new --collection=@ionic-angular/schematics my-app

You should see output like:

Error: Path "/app/app.module.ts" does not exist.
Path "/app/app.module.ts" does not exist.

This is a known issue and there is a work around:

cd /usr/local/lib/node_modules/@angular/cli/node_modules
mkdir @ionic-angular
cp -R /usr/local/lib/node_modules/@ionic-angular/* @ionic-angular/

Now if we try again:

ng new --collection=@ionic-angular/schematics my-app

You should see output like:

create my-app/README.md (1021 bytes)
create my-app/.angular-cli.json (1241 bytes)
create my-app/.editorconfig (245 bytes)
create my-app/.gitignore (516 bytes)
create my-app/src/assets/.gitkeep (0 bytes)
create my-app/src/environments/environment.prod.ts (51 bytes)
create my-app/src/environments/environment.ts (387 bytes)
...
Installing packages for tooling via npm.
...
added 1150 packages in 21.288s
Installed packages for tooling via npm.
Successfully initialized git.
Project 'my-app' successfully created.

Note: We could also have used the Schematics CLI:

schematics @ionic-angular/schematics:application --directory my-app --name myApp 

Generating Components

We'll install @ionic-angular/schematics locally using npm:

cd my-app
npm install @ionic-angular/schematics --save-dev

We can use the ng generate (or just ng g) command to generate Angular components:

ng generate component --collection=@ionic-angular/schematics my-component

You should see output like:

create src/app/my-component/my-component.component.css (0 bytes)
create src/app/my-component/my-component.component.html (31 bytes)
create src/app/my-component/my-component.component.spec.ts (664 bytes)
create src/app/my-component/my-component.component.ts (292 bytes)
update src/app/app.module.ts (420 bytes)

Note: Add the following to your project's .angular-cli.json to define a default collection:

"defaults": {
  "schematics": {
    "collection": "@ionic-angular/schematics"
  },
  ...
}

What's Next

Now that we know Schematics works as expected, anything is possible :)

Source Code:
Resources: