,

Migrating an Angular Nx Workspace to V17

Nov 20, 2023 reading time 8 minutes

Migrating an Angular Nx Workspace to V17

This blog post will guide you through the steps of migrating your Nx and Angular workspace from version 16 to 17.

Migrating an Angular Nx Workspace to V17

Introduction

Angular has released V17 and Nx also has published version 17 of their workspace. Although the versions of Nx and Angular are not connected, both align in this case and in this blog post I want to share the steps I did and had to do when upgrading from Angular and Nx 16 to Angular and Nx 17. Enjoy!

Using the Nx CLI

Nx provides a CLI command to update to the latest versions: nx migrate latest will bring your workspace to the latest versions.

After running the command, the console output will show something like this

And a migrations.json file was created.

You can check the migrations file as described. Note that the node_modules folder now has not been updated! Nothing has been installed until here. Your workspace is not on V17 yet, although the package.json shows you the V17 versions already.

The command line now tells you to run an npm install which you can do, but be aware that sometimes nx created migrations which need a step between the version you are at now, and you want to migrate to.

The flow sometimes is not

  • nx migrate latest
  • updated package.json
  • npm install
  • npx nx migrate --run-migrations
  • Nx runs migrations
  • Profit!

But is sometimes

  • nx migrate latest
  • updated package.json
  • npx nx migrate --run-migrations
  • Nx runs npm install
  • Nx runs migrations
  • Nx has to run npm install again, because some migrations can now be executed based on new versions
  • Nx runs migrations
  • Nx has to run npm install again, because some migrations can now be executed based on new versions
  • Profit!

But Nx got you covered in this case. If you run npx nx migrate --run-migrations Nx will perform the npm install for you, also multiple times if needed.

Updating is only

npx nx migrate latest
npx nx migrate --run-migrations

So without (!) running npm install manually now, we run npx nx migrate --run-migrations and you will see that Nx is running npm install for you as well as the migrations.

We can also see that Nx is running npm install multiple times.

The result is an updated package.json with all the latest versions, as well as an up-to-date node_modules folder. See the git commit here: https://github.com/FabianGosebrink/doggo-rate-app/commit/e3bbc4a8634e6eeffbb1dbbdcf42d00463c9108b


Having done that, you have migrated to the latest version and can start your app to see if everything works. But we are not done yet :) At some workspaces I had the problem that my linting did not work anymore.

Fix linting

When I started to lint my workspace at some workspaces, I had an error like

 Cannot find module '@nrwl/linter/package.json'
   Require stack:
   - <path>\node_modules\nx\src\utils\package-json.js
   - <path>\node_modules\nx\src\utils\package-manager.js
   - <path>\node_modules\nx\bin\init-local.js
   - <path>\node_modules\nx\bin\nx.js
   Pass --verbose to see the stacktrace.

Which confused me, because all the @nrwl packages should be gone and replaced with the @nx namespace instead.

There is an issue on GitHub here that describes this problem very well. Installing the @nrwl/linter solved the problem and let me lint again, but it is NOT recommended to do so. https://github.com/nrwl/nx/issues/20057#issuecomment-1816118936

So I searched in my codebase for the old linter @nrwl/linter:eslint and I found one leftover the migration did not catch for any reason! Replacing it with @nx/eslint:lint solved the issue and I did NOT have to install the outdated linter @nrwl/linter

Digging a little further

I searched for other occurrences of @nrwl and all of a sudden I saw that one project was completely ignored by the migration! However, I compared the files and adjusted it manually erasing all @nrwl occurrences.

For example

Or

Having done that, linting works like a charm again. Perfect!

Fix Testing

The testing was a little bit more of a headache in some workspaces. The problem was, that sometimes I am using helper functions like

export function myFunc1(value: string): string {
	// do something
}

And you want to jest-spy on it, you can import them and spy on them like

import * as myUtils from '@....';

jest.spyOn(myUtils, "myFunc1").mock...

Which all of a sudden did not work anymore because of an error saying Cannot redefine property: xyz . Also described here Stackoverflow.

I was wondering why this was happening and could fix one test by marking the property as configurable

const objectDefineProperty = Object.defineProperty;

Object.defineProperty = function (obj, propertyName, attributes) {
  if (obj['__esModule']) {
    attributes = { ...attributes, configurable: true };
  }
  return objectDefineProperty(obj, propertyName, attributes);
};

The problem was, I needed this for my complete workspace and not in every test case.

To solve this, you can first create a new file on root level and paste the code in. Name the file something like jest.setup.js. Paste the code above into it.

Now we need to tell Nx and jest to use this file when setting up the tests. To do so, enter the jest.preset.js in root level of your workspace and extend it with the setupfiles option

const nxPreset = require('@nx/jest/preset').default;

module.exports = {
  ...nxPreset,
  setupFiles: [path.join(__dirname, 'jest.setup.js')], // ADD THIS
};

If you now let run the tests, it should be running smooth again.

Conclusion

Upgrading an Angular and Nx workspace involves a minimum of three steps: migrating the package.json and getting the application running again, fixing linting issues, and addressing any testing problems.

Nx migrations streamline the process by handling much of the heavy lifting. However, they may occasionally overlook certain aspects. This is not a cause for concern, as you can always refer to other projects within or outside your workspace for guidance. Additionally, you can effortlessly create a new workspace with the latest version, compare the changes, and incorporate them into your existing workspace.

I appreciate the approach to workspace migration, and with these tips, I hope your upgrade process goes smoothly, allowing you to enjoy Angular V17 promptly!

Thank you, Fabian