Migrating from NX 12 to NX 16
Maintainance is a crucial part of software engineering. It is not only about adding new features, but also about keeping the project up to date. This includes updating dependencies, but also updating the tools used to build the project. Once in a while it can happen that the maintainance has suffered and the project is not up to date anymore at all. This happens for my personal projects from time to time. In this article I want to share my experiences and learnings from bringing back a project to an up-to-date state, from migrating an NX 12 project to NX 16.
General migration process in NX workspaces
The NX team provides an exceptionally well designed tool for migrating NX workspaces. You can run a command line tool that will look through each of the affected dependencies and their versions and tries to find a more suitable version without breaking dependency versioning. To start the migration process, the old command has been:
npx nx migrate @nrwl/workspace
This command will run the migration for the
@nrwl/workspace package and all of its dependencies.
Once the command has finished running, it will update the
package.json file with the new versions
and create a
migrations.json. Now you have to verify the changes that have been made to the
package.json file. If you are happy with the changes, you can run the following command to
apply the changes:
npx nx migrate --run-migrations
It will adjust your setup and configuration files and less frequently in your source code to fit the new versions. And here comes the problem migrating too many versions at once: The migration tool is not able to migrate from NX 12 to NX 16. NX 12 has been released on the 4th of August in 2021. At that time NodeJS has been on version 16 in LTS (Long-Term-Support). And therefore also the migration scripts may be written for NodeJS 16. On April 2022 NodeJS 18 has been released. So, it is possible and also likely that some of the migration scripts will fail. The solution is to do the migration in multiple steps.
Luckily, NX provides a way to run the migration to a specific version of your workspace.
Running the migration in multiple steps
First of all, your project should be version controlled, e.g. by Git. Create a new branch on which you will work during the migration. It's essential, because you'll have to revert the automatic changes quite frequently.
Another recommendation is to have NVM (Node Version Manager) installed. It allows you to install multiple versions of NodeJS, so that you can switch between them very easily.
Now you can open
Step 1: Migrate to the release of NodeJS 18 in time
As I said, NodeJS 18 has been released in April 2022. So, you can look at the release table on npmjs and find maybe NX version 14 which has been released on the 10th of April in 2022. So try to run:
npx nx migrate 14.0.0
This should update your
package.json file with the corresponding versions. Now you can run the migration script
as described earlier. Read the command line logs carefully. When you are lucky it succeeds. If it does not succeed
or if it displays any warning messages, you should revert the changes and try to pick an earlier version. Probably
one version of NX 13 will work. If you have found a version that works, you should commit the changes. This is
now your starting point for the next migration. Keep in mind that you do not commit the
migrations.json file and
remove it before you start the next migration.
Step 2: Update NodeJS
Now that you have reached NX 14 you can update your NodeJS version to 18.
Step 3: Continue with the migration process
Now you can continue with the migration process. You can try to migrate to the latest version of NX 14, then NX 15, maybe end of NX 15 and finally NX 16.
Here are some key takeaways:
- Keep NodeJS versions in mind, for a simpler switch of NodeJS versions use NVM
migrations.jsonbefore you start the next migration
- When you notice something like "tsconfig.json file has not been found" or any other warning messages you should revert the changes and try to migrate to an earlier version
- Commit your changes after each successful migration
- Use Git to revert changes when the migration fails