Skip to content

Instantly share code, notes, and snippets.

@bniedermeyer
Created Feb 26, 2019
Embed
What would you like to do?

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.

  1. Generate an Angular workspace with ng new sandbox --skipGit.
  2. Add these two scripts to the sandbox's package.json

https://gist.github.com/9afa901a39707fbd059f69f5c52f5a26

  1. Update the scripts in the root package.json with the following. For this example we'll say that we want to test our ng-add schematic.

https://gist.github.com/305e0ab14f776a915c94c6d7219f483d

  1. 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 link to the sandbox and execute them easily with npm test then 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 schema.json file:

https://gist.github.com/8fbb9744ed918e214c59749abcaf78e0

You would create a schema.model.ts file like so:

https://gist.github.com/33690ad41211e58f40878073637fdc34

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.

https://gist.github.com/ab0e8f33c84fe31e907c58b2d76ac868

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:

https://gist.github.com/e9d2c8c6449838f3cdab1c4b250251bd

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:

https://gist.github.com/134f92bc28fed5c260613c59efff4fd0

Then in collection.json you can mark those other two schematics as private so they aren't accessable outside of the schematic:

https://gist.github.com/969612c44e0f550ab9b1d973d940a31a

Use the 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:

https://gist.github.com/7d93eb9682483410226a8c6b5a0716a0

Then update the root package.json like so:

https://gist.github.com/43a1f0911b595d0089f26e30f30916b5

Adding this additional field will tell npm to only package those files that are not ignored within the src directory. Hooray smaller package sizes!

Conclusion

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment