Node 16 Upgrade

Most of our repositories are currently using Node v8 or v12. As node v8’s support ended on 31st December 2019 and node v12’s support is scheduled to end on 30th April 2022, we’re going to start upgrading our repositories to node v16.

The upgrade will take place in two phases as follows:

Phase 1: Add Node 16 support:

The Arbi-BOM team will generate PRs to upgrade to phase 1 automatically. If you don’t see a PR in your repo that indicates ‘upgrade to node 16’, please reach out to #external-frontend-working-group slack channel. There are some differnces acros repos based on their Workflow files so they won’t all look exactly alike.

  1. Arbi-BOM will do this: Apply node ci modernizer to add node 16 support in GitHub workflows. This workflow will do the following:

    1. Add the matrix with Node versions 12, 14 and 16.

    2. Sets NPM version 8.x.x

  2. Upgrade node and npm version in Dockerfile as well (if exists).

  3. If the package uses node-sass currently, replace it with sass as node-sass is deprecated. Preferably, create a separate PR for this if it brings up a lot of changes.

  4. Run tests with Node 12, 14, and 16, and if any of the tests fail, fix them.

  5. Preferably upgrade edx-owned dependencies to the Node 16 supported version. For some commonly used libraries, Node 16 supported versions are as follows:

    1. Frontend-platform 1.15.1

    2. Frontend-build 9.1.1

    3. Paragon 19.6.0

    4. Frontend-component-header 2.4.5

    5. Frontend-component-footer 10.2.1

  6. Update peer dependencies if possible.

  7. Run npm update to update the dependencies, fix the conflicts and if any tests start to fail either fix them or ask owning the team for help. (optional)

IMPORTANT: While creating the PRs automatically using the cleanup job, the commit type was set to build but it should be feat so anyone working on the PR should update the type in PR title and commit message. (Sorry for this inconvenience).

 

Phase 2: Drop older node versions and fully migrate to Node 16

Drop Node 12 support:

  1. Remove node 12 and 14 from node versions list in strategy matrix for ci workflow.

  2. Switch node version from 12 to 16 in release workflow. For example, here is how node versions are specified in a workflow file: https://github.com/openedx/frontend-app-profile/blob/master/.github/workflows/ci.yml#L17

  3. Update node version in .nvmrc file if exists to something like v16. (for local dev with nvm only)

    1. ensure your .nvmrc has node16 in it or add one. This file is not used in build/deploy pipelines, it’s

    2. just for your local dev comfort.

    3. cd to MFE dir

    4. Install nvm if not already

    5. nvm use This will change your node version to node16. It may ask you to install node16 first.

  4. Verify node version (v16.y.z) and npm versions (v8.y.z)

  5. Delete node_modules/ and package-lock files so they can be regenerated by the new npm version

  6. Make sure the package-lock.json has "lockfileVersion": 2. If it has "lockfileVersion": 1 then run npm install with Node 16 and npm 8 activated via nvm.

  7. Once the PR is ready, request a review from owning team. They’ll review the changes, test on their end and deploy.

(we’ll consider adding a modernizer to automate this phase as well but as of now it’s going to be a manual step taken by the owning team).

If applicable, please update the status in this sheet as well Node 16 upgrade status tracking

Steps to deploy an MFE on Node 16:

The MFEs will still be deployed using node12 in the gocd pipeline at this point, so please do this step once you have updated your Github workflows file, not too long after you merge the prior PR.

IMPORTANT: Ensure that MFE already has support for Node 16 and the package-lock.json has "lockfileVersion": 2. If it has "lockfileVersion": 1 then run npm install with Node 16 and npm 8 activated via nvm and push or go through the open PRs and you might find one automated PR already created by the bot for this purpose.

  1. Set the ‘use_node_16’ flag to true in frontend-generator-inputs.yaml for target MFE. For instance, this PR was created for Frontend-app-authn https://github.com/edx/edx-internal/pull/6393 .

  2. Go to GoCD, trigger the stage pipeline of target MFE and once MFE is deployed on stage, test it.

  3. Once testing is done on stage environment, deploy on production and monitor the changes.

Prioritized Order for the upgrade:

  1. Frontend libraries on which most of the frontend repos are dependent like frontend-build, frontend-enterprise, paragon, eslint-config etc.

  2. List of repos blocking the browserslist work mentioned here Node 16 Upgrade & Shared Browserslist Config.

  3. Remaining repositories.

Note: All the edx-based dependencies for the target repository should be preferably upgraded to node 16 prior to upgrading that repository.

Preferred approach for developers:

Developers should install nvm on their machines to switch between node versions during the upgrade process as some repos will be on node 12 and some will be on node 16 during the upgrade period.

Troubleshooting/tips during node upgrades

A few issues we have run into and potential solutions, example PRs follow.

 

 

Helpful local testing notes for testing out enterprise repos against node 16

To test enterprise MFEs against frontend-enterprise changes locally

  • Install nvm locally (you can use other node manages too this is just what I use)

  • Sync this branch of frontend-enterprise with Adam’s fixes: https://github.com/openedx/frontend-enterprise/pull/250

  • Start completely clean, remove node_modules/, package-lock file (it will all need to be regenerated)

  • update .nvmrc file to v16 if not already

  • nvm use (nvm will ask to install node16 if not already on your system)

  • Verify node is now 16 and npm is v8

node -v; npm -v
  • npm run clean; npm run setup; npm run build

  • All set with frontend-enterprise prep

MFE

  • For MFE: keep what you have, do not upgrade node:

  • Ensure node version by node -v and npm -v is what you used to have.

  • Create/update module.config.js file with the necessary changes such as this (for learner portal)

{ moduleName: '@edx/frontend-enterprise-catalog-search', dir: '../frontend-enterprise/packages/catalog-search', dist: 'src' }, { moduleName: '@edx/frontend-enterprise-utils', dir: '../frontend-enterprise/packages/utils', dist: 'src' },
  • Note: using dist: 'src' mean you will get hot reload without having to rebuild frontend-enterprise all the time

  • Start app. If already running, you first need to ctrl+c to pick up the module.config changes

  • Test the app!

There you go, this is what I think needs to be done. I will be doing this myself, but this is for adventurous souls to explore as they wish!