angularnpmnode-gypnpm-packagelmdb

How can I specify architecture specific npm packages in package-lock.json?


I am developing on Windows and have a CI pipeline in a linux container on GitLab. I can build my Angular application on both systems successfully as long as I do not commit the package-lock.json file. When I commit the package-lock.json (as is recommended) then platform specific win32 dependencies are included, and the build fails in the ci pipeline with:

npm error code 1
npm error path /builds/.../frontend/node_modules/lmdb
npm error command failed
npm error command sh -c node-gyp-build-optional-packages
npm error make: Entering directory '/builds/.../frontend/node_modules/lmdb/build'
npm error   CXX(target) Release/obj.target/lmdb/src/lmdb-js.o
npm error make: Leaving directory '/builds/.../frontend/node_modules/lmdb/build'
npm error /builds/.../frontend/node_modules/node-gyp-build-optional-packages/node-gyp-build.js:85
npm error   throw new Error(errMessage)
npm error   ^
npm error
npm error Error: No native build was found for platform=linux arch=x64 runtime=node abi=127 uv=1 libc=glibc node=22.11.0
npm error     attempted loading from: /builds/.../frontend/node_modules/lmdb and package: @lmdb/lmdb-linux-x64
npm error Error resolving package: Cannot find module '@lmdb/lmdb-linux-x64'
npm error Require stack:
npm error - /builds/.../frontend/node_modules/lmdb/package.json
npm error
npm error     at load.resolve.load.path (/builds/.../frontend/node_modules/node-gyp-build-optional-packages/node-gyp-build.js:85:9)
npm error     at load (/builds/.../frontend/node_modules/node-gyp-build-optional-packages/node-gyp-build.js:28:30)
npm error     at Object.<anonymous> (/builds/.../frontend/node_modules/node-gyp-build-optional-packages/build-test.js:19:19)
npm error     at Module._compile (node:internal/modules/cjs/loader:1546:14)
npm error     at Object..js (node:internal/modules/cjs/loader:1689:10)
npm error     at Module.load (node:internal/modules/cjs/loader:1318:32)
npm error     at Function._load (node:internal/modules/cjs/loader:1128:12)
npm error     at TracingChannel.traceSync (node:diagnostics_channel:315:14)
npm error     at wrapModuleLoad (node:internal/modules/cjs/loader:218:24)
npm error     at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:170:5)
npm error
npm error Node.js v22.11.0
npm error
npm error The failure above indicates the primary issue with the native builds which are included for all major platforms. Will now attempt to build the package locally in case this can be resolved by re-compiling.

the package-lock.json includes:


    "node_modules/@lmdb/lmdb-win32-x64": {
      "version": "3.0.13",
      "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.0.13.tgz",
      "integrity": "sha512-UCrMJQY/gJnOl3XgbWRZZUvGGBuKy6i0YNSptgMzHBjs+QYDYR1Mt/RLTOPy4fzzves65O1EDmlL//OzEqoLlA==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "license": "MIT",
      "optional": true,
      "os": [
        "win32"
      ]
    },
    "node_modules/lmdb": {
      "version": "3.0.13",
      "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.0.13.tgz",
      "integrity": "sha512-UGe+BbaSUQtAMZobTb4nHvFMrmvuAQKSeaqAX2meTEQjfsbpl5sxdHD8T72OnwD4GU9uwNhYXIVe4QGs8N9Zyw==",
      "dev": true,
      "hasInstallScript": true,
      "license": "MIT",
      "dependencies": {
        "msgpackr": "^1.10.2",
        "node-addon-api": "^6.1.0",
        "node-gyp-build-optional-packages": "5.2.2",
        "ordered-binary": "^1.4.1",
        "weak-lru-cache": "^1.2.2"
      },
      "bin": {
        "download-lmdb-prebuilds": "bin/download-prebuilds.js"
      },
      "optionalDependencies": {
        "@lmdb/lmdb-darwin-arm64": "3.0.13",
        "@lmdb/lmdb-darwin-x64": "3.0.13",
        "@lmdb/lmdb-linux-arm": "3.0.13",
        "@lmdb/lmdb-linux-arm64": "3.0.13",
        "@lmdb/lmdb-linux-x64": "3.0.13",
        "@lmdb/lmdb-win32-x64": "3.0.13"
      }
    },

The dependency is pulled in by @angular-devkit/build-angular:

+-- @angular-devkit/build-angular@18.2.6
| +-- @angular/build@18.2.6
| | +-- lmdb@3.0.13
| | | +-- UNMET OPTIONAL DEPENDENCY @lmdb/lmdb-darwin-arm64@3.0.13
| | | +-- UNMET OPTIONAL DEPENDENCY @lmdb/lmdb-darwin-x64@3.0.13
| | | +-- UNMET OPTIONAL DEPENDENCY @lmdb/lmdb-linux-arm@3.0.13
| | | +-- UNMET OPTIONAL DEPENDENCY @lmdb/lmdb-linux-arm64@3.0.13
| | | +-- UNMET OPTIONAL DEPENDENCY @lmdb/lmdb-linux-x64@3.0.13
| | | +-- @lmdb/lmdb-win32-x64@3.0.13

How can I specify multiple platforms to include in the package-lock.json? Or is it good practice to exclude the package-lock.json in the repository?

I also assume that manually editing the package-lock.json is not recommended as those changes are lost on regenerating the file. Is this correct?

I tried to specify multiple os versions in the package.json but this does not have any impact on the package-lock.json file.


Solution

  • Thanks to the support in the comments and answer I found the following solution:

    I added the following optionalDependencies and os to the package.json:

    "os": [
      "win32",
      "linux"
    ],
    "optionalDependencies": {
      "@lmdb/lmdb-linux-x64": "^3.0.13",
      "@lmdb/lmdb-win32-x64": "^3.0.13",
      "@rollup/rollup-win32-x64-msvc": "4.22.4",
      "@rollup/rollup-linux-x64-gnu": "4.22.4"
    }
    

    the rollup packages were needed after I added the lmdb packages due to the following issue: https://github.com/npm/cli/issues/4828

    and I used this comment provided here

    Then I recreated the package-lock.json and it now works locally and in ci.

    It is still very strange that standard angular project requires this additional configuration, but I am glad about this solution. The only other option I saw was to not commit the package-lock.json.