Skip to content

pnpm deploy creates extra directories and fails to hoist transient dependencies #9550

@shellscape

Description

@shellscape

Verify latest release

  • I verified that the issue exists in the latest pnpm release

pnpm version

10.11.0

Which area(s) of pnpm are affected? (leave empty if unsure)

CLI

Link to the code that reproduces this issue or a replay of the bug

No response

Reproduction steps

Please see the full description below.

Describe the Bug

I cannot share the repository that this is reproducible in. I can do a screenshare on a discord call or similar to walk through what I describe below, however. Please let me know if that's something maintainers would like to do.

@KSXGitHub Z suggested I tag you here. pnpm deploy has several new bugs since v10.

  1. Subdirectories are created in workspace packages, when another package or project runs pnpm deploy
  2. Superfluous directory is created in the target project's directory when running pnpm deploy

We're running pnpm deploy like this: pnpm --filter $project --prod deploy $projectRoot/pnpm.out --force. The $project token represents the package/project name. The $projectRoot token represents the package/project absolute path.

Our workspace looks similar to this:

root
|_ packages
  |_ packageA
  |_ packageB
|_ services
  |_ serviceA

Our pnpm-workspace.yaml file looks like this:

packages:
  - 'packages/*'
  - 'services/*'

catalog:
  '@liveblocks/node': 2.18.3
  '@liveblocks/core': 2.18.3
  '@liveblocks/client': 2.18.3

dangerouslyAllowAllBuilds: true
enablePrePostScripts: true
forceLegacyDeploy: true
shamefullyHoist: true

Observe that forceLegacyDeploy is defined. (The new linking strategy for packages is incredibly undesirable for deploying services/APIs/etc on AWS ECS, or anything Docker related.)

When we run pnpm --filter serviceA deploy /path/to/serviceA/pnpm.out the following directories get created:

/root/packageA/services/serviceA/pnpm.out/node_modules/{etc}
/root/packageB/services/serviceA/pnpm.out/node_modules/{etc}
/root/serviceA/services/serviceA/pnpm.out/node_modules/{etc}
/root/serviceA/pnpm.out/node_modules/{etc}

Observe that services/serviceA/pnpm.out/node_modules/{etc} is created within the target serice's directory, in addition to the package directories.

Now, packageA depends on a package from the registry; @dot/log. @dot/log has a dependency on chalk. With v9, /root/serviceA/pnpm.out/node_modules/ included that transient dependency chalk because we were shamefully hoisting. In v10, it does not. Instead, the chalk dependency is for some reason within /root/packageA/services/serviceA/pnpm.out/node_modules/ and not the target pnpm.out directory.

(You may ask why we specify an output directory; We deploy several services in parallel, and we need that boundary separation)

All this said, v10 appears to have some issues with creating extra directories and hoisting.

Expected Behavior

forceLegacyDeploy works in the same, or compatible, manner as the deploy command in v9, does not create additional directories, and properly hoists transient dependencies.

Which Node.js version are you using?

20.19.0

Which operating systems have you used?

  • macOS
  • Windows
  • Linux

If your OS is a Linux based, which one it is? (Include the version if relevant)

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions