NX Generators on Fire

Przemyslaw Nowak
Brainly Technology Blog
3 min readMar 1, 2022
Photo: https://unsplash.com/photos/8KfCR12oeUM

We evaluated monorepo technologies for Brainly's new technology stack some time ago. Finally, we decided to choose NX… and we got another confirmation that it was the right choice!

From Angular Schematics to NX devkit

Our journey began with Angular schematics. Angular schematics are great technology, but it is overcomplicated because of its use of Observables. The purpose of a generator is to interpolate input data into templates and create files. Because of the simplicity of this task, we do not need the added complexity of observables. However, the developer experience suffers due to increased complexity and the steeper learning curve. In this article, I will demonstrate the advantages of NX devkit!

NX DevKit is Promise Based

Promise-based generators seem more relevant to our problems when creating generators (largely i/o related). Promises don't have an additional learning curve as they are well known in the JavaScript community. Using the utilities provided by NX, it's easy to create a generator in record time. I didn't have to write much code while creating Brainly generators. I only used the functions provided by the NX DevKit!

Virtual File System

NX uses a virtual file system until all commands are executed, which means that if we have an error in the middle of our execution, there won't be any incomplete artifacts. NX achieves this using a dry run option.

IDE Plugins

NX provides IDE plugins to make using generators intuitive. Developers can explore which generators are available and view the generator's options using a visual interface. This allows developers to discover and start using generators quickly.

List of available generators
Example of service generator

The Brainiac Service Generator

Brainiac is our internal framework for building applications at Brainly. It's based on the NX DevKit and includes many standard utilities for verifying code quality and generating boilerplate. In the following example, I will show how easy it is to create service hooks in our React application using the Brianaic CLI.

Our generator will do the following:

  • Create a new lib for the service hook (i.e., latestQuestionService to fetch the latest questions)
  • Have an option to choose if we would like to use ReactQuery or Apollo. These are the only two options we support for now.

Generator structure:

As you can see, our generator has two directories: Apollo and ReactQuery. The __tmpl__ extensions denote ejs templates. To generate a simple query hook for Apollo, we can define the following template:

We can do the same thing for ReactQuery:

We then include a schema file that consists of the inputs to be interpolated in the service templates:

Next, well create index.ts file which contains our generator code using the NX DevKit:

This generator does the following:

  • Uses the default lib generator (libraryGenerator) to create a base lib with the required files (tsconfig, eslint, jest, nx.json, workspace.json).
  • Deletes the default source files
  • Creates the new service hook based on library type by interpolating the template values defined inbaseOptions.

Simple, right?

Summary

NX has a lot of advantages over Angular Schematics. First, the developer experience engineering generators are fantastic. Thanks to the NX plugin, generators are self-documenting. We have many more generators in the works. Be sure to follow Brainly's tech blog for future updates. Also, be sure to check out our open positions if you're interested in joining our engineering teams!

--

--