Best practices for Angular Schematics
Angular Schematcs are one of the coolest things to come out of Angular in the past while. With a little bit of work you can build extensions for the Angular CLI that can install and setup libraries in your project, generate code, or make configuration changes easily and in a standard way. They can save you a lot of time in addition to help enforcing coding standards your organization may have.
Here are some best practices that can help save you some time and headaches as you build some awesome schematics.
Use a sandbox project to test your schematics' functionality as you develop
Testing the functionality of your schematics to make sure they behave the way you expect can be tricky. It usually involves having to link your project to another Angular application and then going back and resetting things after you run your schematics before you try again. This can be cumbersome and much more time than I would like. What if I told you it didn't have to be that way?
Kevin Schuchard has a great post where he reccomends packaging your schematics with its own Angular app, which he calls a sandbox, and wire it up with scripts for quick testing and resetting of the project between runs. This helps you move quickly but, even better, helps others to be productive when working on your schematics later on. I highly suggest you go read the article, but here's a quick and dirty setup of a sandbox for your schematics.
- Generate an Angular workspace with
ng new sandbox --skipGit.
- Add these two scripts to the sandbox's
- Update the scripts in the root
package.jsonwith the following. For this example we'll say that we want to test our ng-add schematic.
- Go ahead and setup/commit everything to your git repository at the root of the project (there shouldn't be a secondary one in the sandbox). These scripts will allow us to link our schematics via
npm linkto the sandbox and execute them easily with
npm testthen clean up the sandbox back to it's original state with
npm run clean.
Type your schemas
Schemas are great. They allow you to define what options your schematic is expecting and use dialogs to gather information from the user instead of forcing the user to remember various flags for your schematic. After I create a
schema.json file for my schematics I find it helpful to create an interface that represents that schematic's options.
For example, given this schematic's
You would create a
schema.model.ts file like so:
This way you can use this as the type of the options you pass into the rule factory and you get all the great type checking benefits of Typescriot when working with your rule factorites.
Organize your project by schematic
This may seem like a no-brainer, even the example project gernerated when you run
schematics schematic organizes files like this, but it really is the best way to organize your schematics and adhereing to this will save you a lot of headache down the road. For example if my project had three different schematics (let's call them schematic-a, schematic-b, and schematic-c) you should organize your project like so:
This is similar to how the Angular style guide reccomends organizing your projects into modules by feature.
Create helper schematics
The great thing about schematics is that they can call other schematics! This means you can split up your funcitonality among multiple schematics and make them more modular. For example if I had a schematic that installed some libraries then modified something in the file tree I would create one schematic to handle the installation of the dependencies, one to deal with the file system interactions, and a third to serve as the main schematic that chains the previous two.
Here is what the primary schematic would look like:
collection.json you can mark those other two schematics as private so they aren't accessable outside of the schematic:
files property of
package.json to only publish what you want
As your project grows and becomes more complex you might have more files and directories added to it. This can be great and ease our lives as developers but a lot of that other stuff we use for developing our schematics should not be packaged with the schematics when we publish to npm for others to use (our fancy new sandbox for example). Those files will never be used by end users and can bloat the footprint of our schematics package.
Luckily theres a way to keep our publish process small and simple without needing to change a lot to the project. Simply add the directories you want published to a
files array in your
package.json and let npm take care of the rest! For example, if I only wanted to publish my
src directory when I released my schematics package I would first create a
.npmignore that ensures that none of your *.ts except for definition files will be packaged:
Then update the root
package.json like so:
Adding this additional field will tell npm to only package those files that are not ignored within the
src directory. Hooray smaller package sizes!
Schematics are very exciting and very powerful. There are a lot of techniques that can help to make the building of schematics a lot less difficult. Now you have a few more tools in your schematics toolbox to make sure you can build maintainable and highly performing schematics for your projects. Go forth and see what you can create!