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