-
-
Notifications
You must be signed in to change notification settings - Fork 937
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pnpm deploy
doesn't rewrite workspace:*
dependencies in package.json
#6269
Comments
Had the same problem, and solved it with a script which replaces the // replace-workspace-protocol-by-version.mjs
import fs from 'node:fs';
import path from 'node:path';
import url from 'node:url';
import { Command } from '@commander-js/extra-typings';
import { findWorkspacePackagesNoCheck } from '@pnpm/find-workspace-packages';
const program = new Command().argument(
'<pathtopackagejson>',
'the path to the package.json of which the dependencies using the "workspace:*" protocol should be replaced by the versions present in the monorepo (e.g. "./deployed-package/package.json")'
);
program.parse();
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
const projects = await findWorkspacePackagesNoCheck(path.join(__dirname, '..', '..', '..'));
// first elem of returned array is the root package.json, the monorepo itself --> discard that
const [_rootProject, ...workspaceProjects] = projects;
const absolutePath = path.join(process.cwd(), program.args[0]);
const packageJsonContent = JSON.parse(await fs.promises.readFile(absolutePath, 'utf-8'));
/**
* @param {{[key: string]: string}} dependencies
*/
function replaceWorkspaceProtocolBySpecificVersion(dependencies) {
if (typeof dependencies !== 'object' || dependencies === null) {
return;
}
for (const [pkgName, pkgVersion] of Object.entries(dependencies)) {
if (pkgVersion.startsWith('workspace:')) {
const matchingWorkspaceProject = workspaceProjects.find(
project => project.manifest.name === pkgName
);
if (!matchingWorkspaceProject) {
throw new Error(
`could not replace the workspace protocol of a package, reason: package not found! pkgName=${pkgName}`
);
}
if (!matchingWorkspaceProject.manifest.version) {
throw new Error(
`could not replace the workspace protocol of a package, reason: package has no version! pkgName=${pkgName}`
);
}
dependencies[pkgName] = `^${matchingWorkspaceProject.manifest.version}`;
}
}
}
replaceWorkspaceProtocolBySpecificVersion(packageJsonContent.dependencies);
replaceWorkspaceProtocolBySpecificVersion(packageJsonContent.devDependencies);
replaceWorkspaceProtocolBySpecificVersion(packageJsonContent.peerDependencies);
replaceWorkspaceProtocolBySpecificVersion(packageJsonContent.optionalDependencies);
await fs.promises.writeFile(
absolutePath,
JSON.stringify(packageJsonContent, undefined, 2),
'utf-8'
); # run it against the package.json of the deployed package
node ./replace-workspace-protocol-by-version.mjs ./deployed-package/package.json |
Thanks @pkerschbaum! We ended up working around this by relying on the output of RUN pnpm --recursive run build \
&& pnpm --filter <package> deploy --prod pruned \
&& cd pruned \
&& pnpm pack \
&& tar -zxvf *.tgz package/package.json \
&& rm package.json \
&& mv package/package.json package.json \
&& rm *.tgz |
It appears that it's a careless mistake which still remains in version 8.0.0-rc1. Nevertheless, it is not a significant issue since the code is capable of running without the need for package.json. |
This really depends on your actual use case. In my case, it's a major blocker that requires the workaround 🤷🏻 |
@rijkvanzanten Just curious. If you need to read the version of your dependencies at runtime, you probably want to get it like import libPackageJson from 'lib_name/package.json';
const libVersion = libPackageJson.version; Alternatively you can get the versions from the lock file. |
@alvis It's not about reading the package version (also you can't import |
@rijkvanzanten Right, I guess I got you. Like using |
I'm distributing an app through a Docker image that relies on |
@rijkvanzanten I think your use case example makes a perfect sense to get it sorted asap. |
I believe this is addressed by #6943 Which is not released yet, but hopefully will be soon |
Perfect! Thanks Jacob 🙂 |
I'm experiencing something similar which indicates the broader issue is actually that See this tag for a reproducible example. (This is a POC monorepo, so should be fairly minimal.) In my case, I have several workspace libraries that need to be "published" into the pruned deploy. None of these libraries are correctly processed and so none of them import when the program is executed. @rijkvanzanten's solution is a good start, but unfortunately it doesn't work out of the box for the libraries that are copied into the Since my use-case is also docker, I have a little more leeway to do messy or destructive things, so my work-around is somewhat brutish: RUN \
pnpm --filter my-app build && \
pnpm --filter my-app --prod deploy /pruned/my-app && \
sed -ri 's#"main": "src/(.+)\.ts"#"main": "dist/\1.js"#' /pruned/my-app/node_modules/@my-namespace/*/package.json |
It might be somewhat related, in my case since Point is all of this added complexity and headache could be entirely avoided if |
pnpm version:
7.30.0
Code to reproduce the issue:
Run
pnpm -F <project> deploy
Expected behavior:
When the target directory is created, I expected the
package.json
to be "updated" to include the workspace packages with their respective version numbers similar topnpm pack
orpnpm publish
.Actual behavior:
workspace:*
versions remain in package.json. This in turn means consumers of the output directory can't rely on npm/yarn or any other package manager. A temporary workaround would be topnpm pack
the target directory, then pull the "clean"package.json
from the tarball, and put that back into the target directory of thedeploy
.Additional information:
node -v
prints: v18.12.1The text was updated successfully, but these errors were encountered: