nx icon indicating copy to clipboard operation
nx copied to clipboard

Production built app's package.json dependencies are empty with pnpm@9

Open crbanman opened this issue 1 year ago • 12 comments

Current Behavior

When using pnpm 9.0.1 and creating a production build of an app, the generated package.json and pnpm-lock.yaml files contain no dependencies.

This issue does not occur with [email protected].

Update: I've tested with the the new pnpm 9.0.2 and 9.0.5 releases and this issue still exists.

Expected Behavior

When using pnpm 9.0.1 and creating a production build of an app, the generated package.json and pnpm-lock.yaml files should contain the application's dependencies.

GitHub Repo

https://github.com/crbanman/nx-pnpm-9-issue

Steps to Reproduce

  1. Install [email protected]
  2. pnpm install
  3. pnpm nx run my-new-app:build
  4. Check dist/my-new-app/package.json and dist/my-new-app/pnpm-lock.yaml to see that their missing any dependencies

Nx Report

Node   : 20.11.1
OS     : darwin-arm64
pnpm   : 9.0.1

nx (global)        : 18.0.5
nx                 : 18.3.0
@nx/js             : 18.3.0
@nx/jest           : 18.3.0
@nx/eslint         : 18.3.0
@nx/workspace      : 18.3.0
@nx/devkit         : 18.3.0
@nx/esbuild        : 18.3.0
@nx/eslint-plugin  : 18.3.0
@nx/node           : 18.3.0
@nrwl/tao          : 18.3.0
typescript         : 5.4.5
---------------------------------------
Registered Plugins:
@nx/eslint/plugin
@nx/jest/plugin

Failure Logs

No response

Package Manager Version

No response

Operating System

  • [X] macOS
  • [ ] Linux
  • [ ] Windows
  • [ ] Other (Please specify)

Additional Information

No response

crbanman avatar Apr 16 '24 23:04 crbanman

Experiencing the same issue

triglian avatar Apr 17 '24 07:04 triglian

I also have webpack failing with pnpm@9

sannysoft avatar Apr 17 '24 10:04 sannysoft

Having the same issues when building with @nx/esbuild and passing generatePackageJson. Downgrading pnpm leads to this other issue https://github.com/nrwl/nx/issues/22778

mpsanchis avatar Apr 18 '24 08:04 mpsanchis

Having the same issue here with @nx/webpack:webpack. On the other end, @nx/esbuild:esbuild seems fine. Both using generatePackageJson: true.

alextrep96 avatar Apr 18 '24 13:04 alextrep96

pnpm@9 uses a different lockfile format which isn't supported by nx yet.

alumni avatar Apr 21 '24 20:04 alumni

It looks like #22906 was started last week which will fix this.

crbanman avatar Apr 25 '24 17:04 crbanman

pnpm@9 uses a different lockfile format which isn't supported by nx yet.

lost two days to this 😔 will add a comment to the PR about throwing an error when the lockfileVersion is unsupported

mattfysh avatar Apr 28 '24 07:04 mattfysh

support for pnpm 9 has stalled

mattfysh avatar May 14 '24 03:05 mattfysh

We've also lost several man-hours to this bug. We've created a bash script for our developers using pnpm@^9 to use with Nx.

We manually added pnpm@^8.15.8 as a devDependency in our Nx repos and then use this script when we need to pnpm install anything. For any other pnpm command the pnpm version doesn't matter.

compatible-install.sh

#!/bin/bash
# USAGE:
# Execute this script
# $ ./compatible-install.sh
#
# See this script as a stand-in for `pnpm i`
# which means arguments can be passed onto the script if required
# e.g.
# $ ./compatible-install.sh -Dw typescript@^5.4.0

installWithPnpm8Binary() {
  printf "$(tput setaf 81)%s$(tput sgr0)\n\n" "Installing with pnpm 8"
  pnpm exec pnpm i $@
}

testLockFileVersion() {
  local lockfileVersion
  read -r lockfileVersion<pnpm-lock.yaml
  lockfileVersion=${lockfileVersion#*"'"}
  lockfileVersion=${lockfileVersion:0:1}
  [ $lockfileVersion -eq 6 ] && echo 1 || echo 0
}

init() {
  local pnpmBinDir=$(pnpm bin)
  local globalPnpmMajorVersion=$(pnpm -v)
  globalPnpmMajorVersion=${globalPnpmMajorVersion%%.*}

  if [ $globalPnpmMajorVersion -lt 9 ]; then
    printf "$(tput setaf 81)%s$(tput sgr0)\n\n" "You are already using pnpm 8. Installing as per usual"
    pnpm i $@
  else
    # If pnpm 8 binary isn't where we expect it to be install it without changing the lockfile
    if [ ! -f "${pnpmBinDir}/pnpm" ]; then
      pnpm i --frozen-lockfile --reporter=silent --ignore-scripts --config.dedupe-peer-dependents=false --config.recursive-install=false
    fi
    # do a regular install with the pnpm 8 binary located in the pnpm bin directory
    installWithPnpm8Binary "$@"
  fi

  # Last check to make sure the lockfile version hasn't changed
  if [ $(testLockFileVersion) -ne 1 ]; then
    printf "\n$(tput setaf 226)%s\n$(tput setaf 160)$(tput smso) %s $(tput rmso) $(tput setaf 202)%s$(tput sgr0)\n" \
            "The lockfile version has unexpectedly been updated to v9." \
            "Warning!" \
            "Do not commit the lockfile into git"
  fi
}

if [ -z $(which pnpm) ]; then
  printf "$(tput setaf 226)%s$(tput sgr0)\n" "You should at least have some version of pnpm installed to use this script"
  exit 1
fi

init "$@"

PS: This is an interim solution for our organization as this bug was the last straw and we're moving away from Nx.

phaze-phusion avatar May 14 '24 07:05 phaze-phusion

A workaround for an azure pipeline. It creates a npm project and installs a pnpm, then prepends the 'path' so that the pnpm inside the node_modules is used.

There are some parts u might not need, I just copied our working solution.

installPnpm() {
  local PNPM_VERSION=$1
  local PROJECT_PATH=$2
  local NPMRC_PATH=$3

  echo -e "Installing pnpm@$PNPM_VERSION in $PROJECT_PATH, using npm config:\n\n$(npm config list)\n"

  rm -rf $PROJECT_PATH
  mkdir -p $PROJECT_PATH

  cp $NPMRC_PATH $PROJECT_PATH/.npmrc

  (
    cd $PROJECT_PATH
    npm init -y
    npm i pnpm@$PNPM_VERSION
  )

  local PNPM_PATH="$PROJECT_PATH/node_modules/.bin/pnpm"
  local INSTALLED_PNPM_VERSION=$($PNPM_PATH --version)

  if [ $INSTALLED_PNPM_VERSION != $PNPM_VERSION ]; then
    echo "Failed to install specified pnpm version $PNPM_VERSION, installed version is $INSTALLED_PNPM_VERSION"
    exit 1
  fi

  echo -e "\nInstalled pnpm@$PNPM_VERSION at $PNPM_PATH"
}

prependPath() {
  local PROJECT_PATH=$1

  local PNPM_PATH="$(pwd)/$PROJECT_PATH/node_modules/.bin"

  echo "##vso[task.prependpath]$PNPM_PATH"
}

main() {
  local PNPM_VERSION=$(node -pe "require('./package.json').packageManager.split('@')[1]")
  local PROJECT_PATH='local_pnpm'
  local NPMRC_PATH='.npmrc'

  echo -e "Found pnpm version $PNPM_VERSION in package.json\n"

  installPnpm $PNPM_VERSION $PROJECT_PATH $NPMRC_PATH
  prependPath $PROJECT_PATH
}

main

RobbyRabbitman avatar May 15 '24 10:05 RobbyRabbitman

We've only found this to be an issue for local development. For our pipeline(s) on Gitlab we just use corepack to install pnpm v8.

image: node:20.9.0-bullseye-slim

# ...
  before_script:
    - corepack enable
    - corepack prepare pnpm@latest-8 --activate

phaze-phusion avatar May 15 '24 14:05 phaze-phusion

hi all, if you're affected by this issue and you would like nx to throw errors in future when the lockfile version is higher than what nx supports - please go an add a comment to the PR

https://github.com/nrwl/nx/pull/22906

I looked through the code in the PR but I couldn't find any error being throw, for example if the lockfileVersion is 10 then nx should not try to proceed with faulty lockfile parsing logic

mattfysh avatar May 17 '24 08:05 mattfysh

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.

github-actions[bot] avatar Jun 27 '24 00:06 github-actions[bot]