Modernize Node22 engine dependencies
How to migrate your Optimizely Connect Platform (OCP) app to Node22 runtime version with modernized NodeJS dependencies.
This article outlines the process for migrating an existing Optimizely Connect Platform (OCP) application to the node22 runtime with updated Node.js dependencies, ensuring compatibility with the latest OCP features and improved performance.
Prerequisites
An existing OCP app that uses the node22 runtime with @zaiusinc/app-sdk dependency in 2.x.x version. Verify the runtime version in the app.yml file and the @zaiusinc/app-sdk version in the package.json file.
Why should you migrate?
OCP supports two primary SDK versions for the node22 engine, 2.x.x and 3.x.x. While the 2.x.x SDK version remains supported, migrating your application 3.x.x offers several advantages:
- Modernized dependencies – Benefit from simplified Node.js dependencies, including a transition from
node-fetchlibrary to nativefetchmethods. - Enhanced unit testing – Achieve faster and more reliable unit tests through migration to
vitest. This is an optional step. - Access to new features – Access new features exclusive to
3.x.x. Bug and security fixes are continued for2.x.xversion.
Migrate OCP app to 3.x.x major SDK version
3.x.x major SDK versionComplete the following steps to migrate your OCP app to the 3.x.x major SDK version:
Upgrade required dependencies
- Upgrade libraries to their major
3.x.xmajor versions. The--ignore-enginesflag is necessary to temporarily bypass engine checks during installation.yarn add --ignore-engines "@zaiusinc/[email protected]" "@zaiusinc/[email protected]" "@zaiusinc/eslint-config-presets@^3.0.0" - Remove the
node-fetchdependency and its type definitions.yarn remove --ignore-engines node-fetch yarn remove --ignore-engines @types/node-fetch - Migrate to the native
fetchmethod if your application code uses thenode-fetchlibrary. The nativefetchmethod is a near drop-in replacement ofnode-fetchlibrary, requiring minimal code changes. - Remove all existing ESLint-related dependencies from your
package.jsonfile. Ignore errors about modules not specified in thepackage.jsonfile. The new version of@zaiusinc/eslint-config-presetslibrary includes the necessary dependencies for OCP apps, simplifying the dependencies in yourpackage.jsonfile.yarn remove --ignore-engines @eslint/compat yarn remove --ignore-engines @stylistic/eslint-plugin yarn remove --ignore-engines @typescript-eslint/eslint-plugin yarn remove --ignore-engines @typescript-eslint/parser yarn remove --ignore-engines eslint yarn remove --ignore-engines eslint-plugin-import yarn remove --ignore-engines eslint-plugin-jsdoc yarn remove --ignore-engines eslint-plugin-prefer-arrow yarn remove --ignore-engines eslint-plugin-react yarn remove --ignore-engines tslint yarn remove --ignore-engines @typescript-eslint/eslint-plugin-tslint
Check third-party dependencies and compatibilities
- Remove
yarn.lockandnode_modules, then reinstall dependencies to rebuild them.rm yarn.lock rm -rf node_modules yarn install- If the command succeeds, it means your dependencies are compatible with Node.js 22.
- If it fails, you must upgrade or replace incompatible third-party dependencies. Use
yarn add --ignore-engines [--dev] "<dependency>@<compatible_version>"individually or manually edit thepackage.jsonfile untilyarn installcommand succeeds.
- Run
ocp app validateto upgrade both@zaiusinc/app-sdkand@zaiusinc/node-sdkto the versions currently used by OCP. This command also builds and validates your app.ocp app validate - Approve the changes if the command prompts you to upgrade both
@zaiusinc/app-sdkand@zaiusinc/node-sdkto the latest versions.
Typical migration errors
Implement the following solutions for typical errors related to ESLint, TypeScript, or Jest during your OCP app migration to the node22 runtime:
Resolve compilation errors
Address and fix compilation errors caused by third-party dependency upgrades individually.
Address third-party dependency conflicts
Upgrade third-party dependencies to a compatible version if they conflict with @zaiusinc/app-sdk or @zaiusinc/node-sdk sub-dependencies.
(Optional) Upgrade related dependencies
Consider the following optional steps to upgrade related dependencies to common compatible versions. Skip to Clean up and validate if your app is functional after the initial migration steps.
Upgrade other dev-dependencies used by OCP
- Upgrade other development depdencies to versions compatible with Node.js 22 and
app-sdkv3.x.x. OCP has transitioned fromcopyfilestocpy-clifor improved performance. Replacecopyfilewithcpy-clipackage in your deveopment dependencies.yarn add --dev "cpy-cli@^6.0.0" yarn remove --ignore-engines copyfiles - Modify the
buildscript in yourpackage.jsonfile to usecpyinstead ofcopyfiles. The updatedbuildscript should resemble the following example:"build": "yarn && npx rimraf remove dist && npx tsc && cpy app.yml dist && cpy --up 1 \"src/**/*.{yml,yaml}\" dist", - Run the
ocp app validatecommand to verify these changes. This command should run successfully. If an error occurs, it likely indicates a version conflict with a third-party dependency. Remove these conflicts individually.ocp app validate
Migrate to vitest from Jest
vitest from JestThe 3.x.x version of OCP SDKs leverages vitest instead of Jest. Migrating to vitest offers several key benefits, including the following:
- Improved speed and performance –
vitestsignificantly improves test execution speed, particularly for projects with extensive test suites. - Simplified dependencies –
vitestprovides support for TypeScript and ESM, removing the complex configurations often required byts-jest. This native support enhances test reliability, ensuring that if your app functions, your tests do too. - Increased compatibility –
vitestis largely compatible with Jest, minimizing the need for extensive test rewrites during migration.
Execute the following steps to migrate to vitest:
-
Remove the default
Jestdependencies used by the OCP app. If your application uses custom Jest dependencies, remove them from thepackage.jsonas well.yarn remove --ignore-engines @types/jest yarn remove --ignore-engines jest yarn remove --ignore-engines ts-jest yarn remove --ignore-engines eslint-plugin-jest -
Add the
vitestdependency to your project.yarn add --dev "vitest" -
Update the
testscript in yourpackage.jsonfile to usevitestinstead ofjest. The updatedtestscript should resemble the following example:"test": "npx vitest run --passWithNoTests" -
Create a
vitest.config.tsroot folder of your application with the following content:import { defineConfig } from 'vitest/config'; process.env.ZAIUS_ENV = 'test'; // Load test environment variables import('dotenv').then(dotenv => { dotenv.config({ path: '.env.test' }); }); export default defineConfig({ test: { environment: 'node', include: ['src/**/*.test.ts'], exclude: ['node_modules', 'dist'], coverage: { provider: 'v8', include: ['src/**/*.ts'], exclude: ['src/test/**/*', 'src/**/index.ts'], }, globals: true, }, }); -
Modify your
eslint.config.mjsESLint configuration by removing references tojestand optionally adding thevitestlinter. Execute the following steps:- Remove the import of the
eslint-plugin-jestplugin,import jest from 'eslint-plugin-jest'; - Remove
jestfrom the plugin list. - Remove all custom rules that contain
jest, for example,jest/unbound-method - Optionally, add the
@zaiusinc/eslint-config-presets/vitest.mjslinter configuration. The default configuration file used by OCP app templates should resemble the following example:import node from '@zaiusinc/eslint-config-presets/node.mjs'; import vitest from '@zaiusinc/eslint-config-presets/vitest.mjs'; export default [ ...node, ...vitest, { files: ['**/*.test.ts'], rules: { '@typescript-eslint/unbound-method': 'off' }, }];
- Remove the import of the
-
Migrate your tests to
vitest.vitestis a near drop-in replacement for Jest, but you need to replace references tojestwithvitestin your code. The main changes involve addingvitestrelated imports and replacingjestreferences withvireferences. Execute the following steps:- Import
vitestdependencies in every test (*.test.ts) file.import { vi, beforeEach, afterEach, describe, it, expect } from 'vitest'; - Perform the following replacements in your code base:
- Replace
as jest.Mockwithas ReturnType<typeof vi.fn>. - Replace
jest.withvi..
- Replace
- Automate these replacements using the following commands:
find . -name "*.test.ts" -not -path "*/node_modules/*" -exec sed -i '' '1s/^/import { vi, beforeEach, afterEach, describe, it, expect } from "vitest";\n/' {} + find . -type f \( -name "*.ts" -o -name "*.tsx" \) -not -path "*/node_modules/*" -exec sed -i '' 's/as jest\.Mock/as ReturnType<typeof vi.fn>;/g' {} + find . -type f \( -name "*.ts" -o -name "*.tsx" \) -not -path "*/node_modules/*" -exec sed -i '' 's/jest\./vi./g' {} + - Run
yarn lint --fixto resolve any linter issues.yarn lint --fix - Run
yarn build testuntil all compilation issues are resolved and all tests pass. Refer to the officialvitestguide for details.yarn build test - Remove
jest.config.jsfile.rm jest.config.js
- Import
-
Run
ocp app validatecommand to verify the changes:ocp app validate -
Fix the issues individually if the compilation or tests fail.
Clean up and validate
Complete the following steps:
- Remove
yarn.lockandnode.modules, then reinstall dependencies to ensure a clean build.rm yarn.lock rm -rf node_modules yarn install - Run a final validation check on your app.
ocp app validate - Deploy a new
-devor-betaversion of your app to OCP and conduct thorough testing to confirm successful operation.
Updated 3 days ago
