Migrating from Nunjucks to React render engine

Found an error? Have a suggestion?Edit this page on GitHub

The AsyncAPI Generator is moving away from Nunjucks templates in favor of React templates. This guide will help you migrate your existing Nunjucks templates to React. For a comprehensive understanding of why we introduced React as an alternative in 2021 and why we're now removing Nunjucks entirely, please read our article React as a Generator Engine. The principles discussed in this article still apply to our current transition.

Step-by-step migration guide

1. Update package.json

Change your template configuration in package.json:

1{
2"generator": {
3"renderer": "react"
4}
5}

Once the deprecation period has ended, and we remove the default Nunjucks, the React render engine will be used by default and this setting will no longer be needed to configure

2. Install dependencies

Install the necessary React dependencies:

npm install @asyncapi/generator-react-sdk

3. File naming

In Nunjucks, the template's filename directly corresponds to the output file. For example, a template named index.html will generate an index.html file.

In React, the filename of the generated file is not controlled by the file itself, but rather by the File component. The React component itself can be named anything with a .js extension because the output filename is controlled by the name attribute of the File component used inside the template file. Below you can see some examples of filenames:

Nunjucks: index.html React: index.js or index.html.js or anything-you-want.js

4. Basic template structure

Nunjucks:

1<h1>{{ asyncapi.info().title() }}</h1>
2<p>{{ asyncapi.info().description() }}</p>

React:

1import { File } from '@asyncapi/generator-react-sdk';
2
3export default function({ asyncapi }) {
4  return (
5    <File name="index.html">
6      <h1>{asyncapi.info().title()}</h1>
7      <p>{asyncapi.info().description()}</p>
8    </File>
9  );
10}

5. Macros and Partials

Replace macros with React components:

Nunjucks:

1{% macro renderChannel(channel) %}
2  <div class="channel">
3    <h3>{{ channel.address() }}</h3>
4    <p>{{ channel.description() }}</p>
5  </div>
6{% endmacro %}
7
8{{ renderChannel(someChannel) }}

React:

1// components/Channel.js
2import { Text } from '@asyncapi/generator-react-sdk';
3
4export function Channel({ channel }) {
5  return (
6    <Text>
7      <div className="channel">
8        <h3>{channel.address()}</h3>
9        <p>{channel.description()}</p>
10      </div>
11    </Text>
12  );
13}
14
15// Main template
16import { File, Text } from '@asyncapi/generator-react-sdk';
17import { Channel } from './components/Channel';
18
19export default function({ asyncapi }) {
20  return (
21    <File name="channels.html">
22      <Text>
23        <h2>Channels</h2>
24      </Text>
25      {asyncapi.channels().map(channel => (
26        <Channel channel={channel} />
27      ))}
28    </File>
29  );
30}

6. File template

Check the detailed guide on file templates to learn what is the difference between templating multiple file outputs in Nunjucks and React.

7. Models generation

If you have a template written with Nunjucks, it is almost certain that you have your own custom models, classes, or types templates in place. Instead of migrating them to React render engine we strongly advise you to delegate models generation to AsyncAPI Modelina project. Learn more about how to add models generation using Modelina.

Additional Resources and Information

Template Examples

For a complete example of React features in use, please refer to the AsyncAPI Template for Generator Templates. The master branch demonstrates all React features, while the nunjucks branch shows the old Nunjucks implementation. This comparison can be particularly helpful in understanding the differences and migration process.

Filters to Helpers

If you've been using Nunjucks filters placed in the filters directory, you can still use this functionality in React. However, they should be treated as normal functions that you import into your components. We recommend renaming the filters directory to helpers to better reflect their new usage in React.

Hooks Remain Unchanged

It's important to note that hooks remain unchanged in this migration process. Hooks are not related to the render engine functionality, so you can continue to use them as you have been.

Testing your migration

After migrating, test your template thoroughly:

  1. Run the generator using your new React template
  2. Compare the output with the previous Nunjucks template output
  3. Check for any missing or incorrectly rendered content

Consider implementing snapshot tests for your template before starting the migration. This will ease the review of changes in comparing the content rendered after render engine changes. Snapshot tests allow you to have tests that will persist expected output from Nunjucks template, and compare it with output generated after the migration. Check out an example of such snapshot integration test for our internal react template we use for development and testing.

Conclusion

Migrating from Nunjucks to React templates may require some initial effort, but it will result in more maintainable code. You can learn more about why we introduced the React render engine from article React as a Generator Engine.

Was this helpful?
Help us improve the docs by adding your contribution.
OR
Github:AsyncAPICreate Issue on GitHub