Skip to content

Upgrade NPM and Node to current LTS for compatibility with M1/arm64 CPUs#161

Merged
labkey-nicka merged 7 commits intodevelopfrom
fb_updateNodeNPM
Jan 6, 2022
Merged

Upgrade NPM and Node to current LTS for compatibility with M1/arm64 CPUs#161
labkey-nicka merged 7 commits intodevelopfrom
fb_updateNodeNPM

Conversation

@labkey-jeckels
Copy link
Copy Markdown
Contributor Author

@labkey-nicka thanks for the pointer to the NPM/Node pairings.

So far I'm the only person I know building LabKey on a M1 chip. I was amazed when everything appeared to just work when I swapped versions so thought we could do a 21.7->21.11->develop workflow but starting in develop is indeed wiser. Hopefully the jbrowse build is happier with the Node update here.

@labkey-jeckels
Copy link
Copy Markdown
Contributor Author

@labkey-nicka @cnathe does the npm failure in BimberLabKeyModules/mcc make any sense to you? If not, I can reach out to Ben and ask him to take a look.

https://teamcity.labkey.org/buildConfiguration/bt312/1633193

Error: double-loading config "/mnt/teamcity/work/1a7cac15859b185e/test_secure/npm/npmrc" as "global", previously loaded as "user"
16:10:23 at Config.[loadObject] (/mnt/teamcity/work/1a7cac15859b185e/server/modules/BimberLabKeyModules/mcc/.gradle/nodejs/node-v16.13.1-linux-x64/lib/node_modules/npm/node_modules/@npmcli/config/lib/index.js:451:13)
16:10:23 at /mnt/teamcity/work/1a7cac15859b185e/server/modules/BimberLabKeyModules/mcc/.gradle/nodejs/node-v16.13.1-linux-x64/lib/node_modules/npm/node_modules/@npmcli/config/lib/index.js:489:32
16:10:23 at async Config.[loadFile] (/mnt/teamcity/work/1a7cac15859b185e/server/modules/BimberLabKeyModules/mcc/.gradle/nodejs/node-v16.13.1-linux-x64/lib/node_modules/npm/node_modules/@npmcli/config/lib/index.js:488:5)
16:10:23 at async Config.load (/mnt/teamcity/work/1a7cac15859b185e/server/modules/BimberLabKeyModules/mcc/.gradle/nodejs/node-v16.13.1-linux-x64/lib/node_modules/npm/node_modules/@npmcli/config/lib/index.js:268:5)
16:10:23 at async Object.[_load] (/mnt/teamcity/work/1a7cac15859b185e/server/modules/BimberLabKeyModules/mcc/.gradle/nodejs/node-v16.13.1-linux-x64/lib/node_modules/npm/lib/npm.js:230:5)

@cnathe
Copy link
Copy Markdown
Contributor

cnathe commented Dec 14, 2021

@labkey-nicka @cnathe does the npm failure in BimberLabKeyModules/mcc make any sense to you? If not, I can reach out to Ben and ask him to take a look.

https://teamcity.labkey.org/buildConfiguration/bt312/1633193

Hmmm, no. I have not seen the Error: double-loading config before. That is odd. Do you see that locally or is it just on TeamCity?

@labkey-jeckels
Copy link
Copy Markdown
Contributor Author

@cnathe I hadn't tried building the MCC module locally until now, but it succeeded for me.

@labkey-jeckels
Copy link
Copy Markdown
Contributor Author

On a rerun attempt on TeamCity, both the MCC and ELISA modules failed with the same error. I wonder if there's a race condition or shared configuration that's causing problems across parallel NPM builds.

@labkey-nicka
Copy link
Copy Markdown
Contributor

On a rerun attempt on TeamCity, both the MCC and ELISA modules failed with the same error. I wonder if there's a race condition or shared configuration that's causing problems across parallel NPM builds.

One thing I would investigate is if we need to rehydrate the package-lock files when migrating from NPM v6 to v8. I know they changed some of the behaviors in terms of what packages get downloaded (e.g. I believe they now download all the "dev dependencies" for each package or some such). This could possibly be something that only breaks certain scenarios (like MCC and ELISA) so could have targeted package-lock updates for this set of PRs.

Copy link
Copy Markdown
Contributor

@labkey-nicka labkey-nicka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is some of my initial assessments. I still need to more throughly test our hot reloading scenarios (i.e. npm run start-link).

Comment thread gradle.properties
# The version of npm corresponds to the given version of node
npmVersion=6.14.13
nodeVersion=14.17.1
npmVersion=8.1.2
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pulled these changes and ran the following command:

./gradlew cleanBuild && ./gradlew deployApp

For my initial run this failed because our "cleanBuild" command intentionally does not actually clean up node_modules directories in LK modules.

Screen Shot 2021-12-16 at 3 09 39 PM

The remedy was to go in and rm -rf node_modules in the biologics module and then reran the build commands. This will only really be an issue for developers who locally pull these changes so we'll want to advise them to take action to clean these up after this is merged. @labkey-susanh may know if there is already a command in Gradle to ask it to clean up the node_modules directories which could be useful for the initial run after pulling.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gradle command cleanNodeModules will go through all modules with a package.lock file and remove any node_modules directories it finds.

Comment thread gradle.properties
npmVersion=6.14.13
nodeVersion=14.17.1
npmVersion=8.1.2
nodeVersion=16.13.1
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I alluded to previously, starting in NPM v7 they changed how it resolves peer dependencies. This doesn't cause a problem for our initial unchanged (NPM v6) package-lock.json files, however, npm does warn about this:

Screen Shot 2021-12-16 at 3 18 27 PM

As a result, when I attempted to rehydrate Biologics' package-lock.json with NPM v8 I ran into a common failure mode where there is a collision in our peer dependencies (this actually resulted in an infinite loop where I has to kill -9 the process ... but I digress):

Screen Shot 2021-12-16 at 3 22 34 PM

The quick solution is to always use a new flag introduced in npm v7 called legacy-peer-deps (docs here) when rehydrating. Like this:

npm install --legacy-peer-deps

This is not something we will want to be doing for very long -- if at all. We may want to spend some time to see if we can untangle these dependencies by either upgrading and/or removing out-of-date dependencies. That, however, can be a bit time consuming so the flag gives us a chance to keep going and follow up on individual modules when we update them. That said, we'd need to let folks know about this new flag and when/why to use it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend we move ahead with informing folks about the --legacy-peer-deps flag when it comes to rehydrating/updating packages.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to dive a bit deeper today and have several findings to report:

  1. Although we can specify the --legacy-peer-deps flag this still produces a v2 package-lock.json file. This means that any subsequent package updates we perform within a module/package will initially result in updating the package-lock.json from v1 (npm 6) to v2 (npm 7+). Due to this behavior, I think we should consider updating all associated package-lock.json's we "actively" maintain in coordinated PRs with these changes. I don't think this needs to be all packages initially as we can do follow-up updates to modules/packages we touch less often.
  2. As a result of this update we'll be updating the version of Node that our unit tests run on. I've seen some failure locally after updating. We will need to coordinate PRs to fix these tests.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Further update:

I was able to fix issues (e.g. webpack/webpack-cli#2990) seen using npm run start-link by updating @labkey/build to use more recent versions. These changes will be coordinated. Additonally, I've updated the associated package-lock.json to v2 for LKB, LKSM, Inventory, @labkey/workflow, and @labkey/freezermanager. I've opened associated branches on LKB, LKSM, and Inventory so far and will do platform in the next iteration.

@labkey-nicka
Copy link
Copy Markdown
Contributor

labkey-nicka commented Dec 17, 2021

On a rerun attempt on TeamCity, both the MCC and ELISA modules failed with the same error. I wonder if there's a race condition or shared configuration that's causing problems across parallel NPM builds.

One thing I would investigate is if we need to rehydrate the package-lock files when migrating from NPM v6 to v8. I know they changed some of the behaviors in terms of what packages get downloaded (e.g. I believe they now download all the "dev dependencies" for each package or some such). This could possibly be something that only breaks certain scenarios (like MCC and ELISA) so could have targeted package-lock updates for this set of PRs.

A quick update on minor investigation of the MCC/Elisa module build failures. It looks like these errors are not specifically related to any one module but rather an issue with how TeamCity is passing/configuring the NPM config that is used. I don't have a specific answer here to solve this but these env variables found in the test parameters configuration seem like the right place to look:

image

The fact that both of these point to the same place appears to be resulting in a "double loading" that is violation in these versions of node/npm. Might just try removing the "global" config declaration so that only "user" is specified.

Configuration of npmrc docs: https://docs.npmjs.com/cli/v8/configuring-npm/npmrc

Update

I was able to reproduce this locally by specifying the same flags as configured on TC:

export NPM_CONFIG_GLOBALCONFIG=/same/path
export NPM_CONFIG_USERCONFIG=/same/path

image

This failure went away when I commented either of them out (tried both ways). So, yes, I think removing one of these from the TC configuration should clear this issue up.

@labkey-nicka
Copy link
Copy Markdown
Contributor

I've reached out to @labkey-martyp and @labkey-ians about testing this in Windows & Linux development environments besides OSX.

@labkey-martyp
Copy link
Copy Markdown
Contributor

I've reached out to @labkey-martyp and @labkey-ians about testing this in Windows & Linux development environments besides OSX.

Everything worked the same for me on Windows as others noted above. Gradlew cleanbuild then deployapp worked fine. Running start-link required re-populating package-lock.json files with --legacy-peer-deps flag. I would suggest we just do a new commit of those re-populated package-lock.json files along with this commit. As long as the lockfileVersion is 2 that will be compatible with old and new NPM peer dependency behavior.

@Sigmonia
Copy link
Copy Markdown
Contributor

The new branches worked relatively smoothly for me. Just did a gradlew cleanNode, gradlew cleanBuild (not sure it was truly necessary), and then gradlew dA. Did need a yarn install && yarn run build in my components enlistment before start-link would work in SampleManager, but might have been an artifact of timing with Nick's changes to package-lock.

@labkey-nicka labkey-nicka self-assigned this Jan 4, 2022
@labkey-martyp
Copy link
Copy Markdown
Contributor

I've reached out to @labkey-martyp and @labkey-ians about testing this in Windows & Linux development environments besides OSX.

Everything worked the same for me on Windows as others noted above. Gradlew cleanbuild then deployapp worked fine. Running start-link required re-populating package-lock.json files with --legacy-peer-deps flag. I would suggest we just do a new commit of those re-populated package-lock.json files along with this commit. As long as the lockfileVersion is 2 that will be compatible with old and new NPM peer dependency behavior.

Verified the latest changes on Windows. No longer needed to delete node_modules or repopulate package-lock.json with --legacy-peer-deps. Tested hot reloading changes on SM, LKB, WF, ui-comp, and platform assays. Everything working as before with no extra steps needed.

@labkey-nicka labkey-nicka merged commit 78f8772 into develop Jan 6, 2022
@labkey-nicka labkey-nicka deleted the fb_updateNodeNPM branch January 6, 2022 20:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants